{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Title: #Maximum Product of Word Lengths"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Difficulty: #Medium"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Category Title: #Algorithms"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Tag Slug: #bit-manipulation #array #string"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Name Translated: #位运算 #数组 #字符串"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Solution Name: maxProduct"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Translated Title: #最大单词长度乘积"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Translated Content:\n",
    "<p>给你一个字符串数组&nbsp;<code>words</code> ，找出并返回 <code>length(words[i]) * length(words[j])</code>&nbsp;的最大值，并且这两个单词不含有公共字母。如果不存在这样的两个单词，返回 <code>0</code> 。</p>\n",
    "\n",
    "<p>&nbsp;</p>\n",
    "\n",
    "<p><strong>示例&nbsp;1：</strong></p>\n",
    "\n",
    "<pre>\n",
    "<strong>输入：</strong>words = <code>[\"abcw\",\"baz\",\"foo\",\"bar\",\"xtfn\",\"abcdef\"]</code>\n",
    "<strong>输出：</strong><code>16 \n",
    "<strong>解释</strong></code><strong>：</strong><code>这两个单词为<strong> </strong>\"abcw\", \"xtfn\"</code>。</pre>\n",
    "\n",
    "<p><strong>示例 2：</strong></p>\n",
    "\n",
    "<pre>\n",
    "<strong>输入：</strong>words = <code>[\"a\",\"ab\",\"abc\",\"d\",\"cd\",\"bcd\",\"abcd\"]</code>\n",
    "<strong>输出：</strong><code>4 \n",
    "<strong>解释</strong></code><strong>：</strong>这两个单词为 <code>\"ab\", \"cd\"</code>。</pre>\n",
    "\n",
    "<p><strong>示例 3：</strong></p>\n",
    "\n",
    "<pre>\n",
    "<strong>输入：</strong>words = <code>[\"a\",\"aa\",\"aaa\",\"aaaa\"]</code>\n",
    "<strong>输出：</strong><code>0 \n",
    "<strong>解释</strong></code><strong>：</strong><code>不存在这样的两个单词。</code>\n",
    "</pre>\n",
    "\n",
    "<p>&nbsp;</p>\n",
    "\n",
    "<p><strong>提示：</strong></p>\n",
    "\n",
    "<ul>\n",
    "\t<li><code>2 &lt;= words.length &lt;= 1000</code></li>\n",
    "\t<li><code>1 &lt;= words[i].length &lt;= 1000</code></li>\n",
    "\t<li><code>words[i]</code>&nbsp;仅包含小写字母</li>\n",
    "</ul>\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Description: [maximum-product-of-word-lengths](https://leetcode.cn/problems/maximum-product-of-word-lengths/description/)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Solutions: [maximum-product-of-word-lengths](https://leetcode.cn/problems/maximum-product-of-word-lengths/solutions/)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "test_cases = ['[\"abcw\",\"baz\",\"foo\",\"bar\",\"xtfn\",\"abcdef\"]', '[\"a\",\"ab\",\"abc\",\"d\",\"cd\",\"bcd\",\"abcd\"]', '[\"a\",\"aa\",\"aaa\",\"aaaa\"]']"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maxProductDifference(self, nums: List[int]) -> int:\n",
    "        nums.sort()\n",
    "        return nums[-1]*nums[-2]-nums[0]*nums[1]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maxProductDifference(self, nums: List[int]) -> int:\n",
    "        nums.sort()  # 将数组按升序排序\n",
    "        return nums[-1] * nums[-2] - nums[0] * nums[1]  # 返回最大乘积差"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maxProductDifference(self, nums: List[int]) -> int:\n",
    "        nums.sort(reverse=True)\n",
    "        return (nums[0] * nums[1]) - (nums[-1] * nums[-2])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maxProductDifference(self, nums: List[int]) -> int:\n",
    "        #找到两个最大的，找到两个最小的\n",
    "        num_max, num_min = 1,1\n",
    "        num_max *= max(nums)\n",
    "        nums.remove(max(nums))\n",
    "        num_max *= max(nums)\n",
    "\n",
    "        num_min *= min(nums)\n",
    "        nums.remove(min(nums))\n",
    "        num_min *= min(nums)\n",
    "\n",
    "        return num_max-num_min"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maxProductDifference(self, nums: List[int]) -> int:\n",
    "        nums.sort()\n",
    "        return nums[-1]*nums[-2] - nums[0]*nums[1]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maxProductDifference(self, nums: List[int]) -> int:\n",
    "        nums.sort()\n",
    "        return (nums[-1] * nums[-2]) - (nums[0] * nums[1])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maxProductDifference(self, nums: List[int]) -> int:\n",
    "        nums.sort(reverse=True)\n",
    "        return nums[0]*nums[1] - nums[-1]*nums[-2]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maxProductDifference(self, nums: List[int]) -> int:\n",
    "\n",
    "        max1=max(nums)\n",
    "        nums.remove(max1)\n",
    "        max2=max(nums)\n",
    "        min1=min(nums)\n",
    "        nums.remove(min1)\n",
    "        min2=min(nums)\n",
    "        return max1*max2-min1*min2"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maxProductDifference(self, nums: List[int]) -> int:\n",
    "        if len(nums) < 4:\n",
    "            return 0\n",
    "        nums.sort()\n",
    "        return nums[-1] * nums[-2] - nums[0] * nums[1]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maxProductDifference(self, nums: List[int]) -> int:\n",
    "        nums.sort()\n",
    "        return nums[-1] * nums[-2] - nums[1] * nums[0]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maxProductDifference(self, nums: List[int]) -> int:\n",
    "        nums.sort()\n",
    "        return (nums[-1] * nums[-2]) - (nums[0] * nums[1])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maxProductDifference(self, nums: List[int]) -> int:\n",
    "        nums.sort()\n",
    "        return nums[-1] * nums[-2] - nums[0] * nums[1]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maxProductDifference(self, nums: List[int]) -> int:\n",
    "        nums.sort()\n",
    "        return nums[-1] * nums[-2] - nums[0] * nums[1]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maxProductDifference(self, nums: List[int]) -> int:\n",
    "        nums.sort()\n",
    "        return nums[-1] * nums[-2] - nums[0] * nums[1]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maxProductDifference(self, nums: List[int]) -> int:\n",
    "        nums.sort(key=lambda x: -x)\n",
    "        return nums[0] * nums[1] - nums[-2] * nums[-1]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maxProductDifference(self, nums: List[int]) -> int:\n",
    "        nums.sort()\n",
    "        return nums[-1]*nums[-2] - nums[0]*nums[1]\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maxProductDifference(self, nums: List[int]) -> int:\n",
    "        nums.sort()\n",
    "\n",
    "        \n",
    "        return nums[-1]*nums[-2]-nums[0]*nums[1]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maxProductDifference(self, nums: List[int]) -> int:\n",
    "        nums.sort()\n",
    "        a = nums[-1]\n",
    "        b = nums[-2]\n",
    "        c = nums[0]\n",
    "        d = nums[1]\n",
    "        return a*b-c*d"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maxProductDifference(self, nums: List[int]) -> int:\n",
    "        numsSize = len(nums)\n",
    "        nums = list(sorted(nums))\n",
    "        return nums[numsSize - 1] * nums[numsSize - 2] - nums[0] * nums[1]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maxProductDifference(self, nums: List[int]) -> int:\n",
    "        nums.sort()\n",
    "        return nums[-1] * nums[-2] - nums[0] * nums[1]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maxProductDifference(self, nums: List[int]) -> int:\n",
    "        nums.sort()\n",
    "        return nums[-1]*nums[-2] - nums[0]*nums[1]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maxProductDifference(self, nums: List[int]) -> int:\n",
    "        max1, max2 = 0, 0\n",
    "        min1, min2 = 10001, 10001\n",
    "        for n in nums:\n",
    "            if n > max1:\n",
    "                max2 = max1\n",
    "                max1 = n\n",
    "            elif n > max2:\n",
    "                max2 = n\n",
    "\n",
    "            if n < min1:\n",
    "                min2 = min1\n",
    "                min1 = n\n",
    "            elif n < min2:\n",
    "                min2 = n\n",
    "        return max1 * max2 - min1 * min2\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maxProductDifference(self, nums: List[int]) -> int:\n",
    "        maxNum1=max(nums)\n",
    "        minNum1=min(nums)\n",
    "        nums.remove(maxNum1)\n",
    "        nums.remove(minNum1)\n",
    "        maxNum2=max(nums)\n",
    "        minNum2=min(nums)\n",
    "        return maxNum1*maxNum2-minNum1*minNum2"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maxProductDifference(self, nums: List[int]) -> int:\n",
    "        nums.sort()\n",
    "        return nums[-1]*nums[-2] - nums[0]*nums[1]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maxProductDifference(self, nums: List[int]) -> int:\n",
    "        nums.sort()\n",
    "        return nums[len(nums)-1]*nums[len(nums)-2]-nums[0]*nums[1]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maxProductDifference(self, nums: List[int]) -> int:\n",
    "        nums.sort()\n",
    "        return nums[-1]*nums[-2]-nums[0]*nums[1]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maxProductDifference(self, nums: List[int]) -> int:\n",
    "        nums.sort()\n",
    "        n=len(nums)\n",
    "        return nums[n-1]*nums[n-2]-nums[0]*nums[1]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maxProductDifference(self, nums: List[int]) -> int:\n",
    "        length = len(nums)\n",
    "        nums.sort(reverse = False)\n",
    "        max1 = nums[length-1]\n",
    "        max2 = nums[length-2]\n",
    "        min1 = nums[0]\n",
    "        min2 = nums[1]\n",
    "        return max1*max2 - min1*min2"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maxProductDifference(self, nums: List[int]) -> int:\n",
    "        nums.sort()\n",
    "        print(nums.sort())\n",
    "        res=nums[-1]*nums[-2]-nums[0]*nums[1]\n",
    "        return res"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maxProductDifference(self, nums: List[int]) -> int:\n",
    "        nums.sort()\n",
    "        return nums[len(nums) - 1]*nums[len(nums) - 2] - nums[0]*nums[1]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maxProductDifference(self, nums: List[int]) -> int:\n",
    "        nums.sort()\n",
    "        return (nums[-1] * nums[-2]) - (nums[0] * nums[1])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maxProductDifference(self, nums: List[int]) -> int:\n",
    "        nums.sort()\n",
    "        return nums[-1] * nums[-2] - nums[0] * nums[1]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maxProductDifference(self, nums: List[int]) -> int:\n",
    "        nums.sort()\n",
    "        return nums[-1] * nums[-2] - nums[0] * nums[1]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\r\n",
    "    def maxProductDifference(self, nums: List[int]) -> int:\r\n",
    "        nums.sort()\r\n",
    "        return nums[-1] * nums[-2] - nums[0] * nums[1]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maxProductDifference(self, nums: List[int]) -> int:\n",
    "        nums.sort()\n",
    "        return nums[- 1]*nums[- 2] - nums[0]*nums[1]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maxProductDifference(self, nums: List[int]) -> int:\n",
    "        min1 = 10001\n",
    "        min2= 0\n",
    "        max1 = 0\n",
    "        max2 = 0\n",
    "        \n",
    "        for i in nums:\n",
    "            if i < min1:\n",
    "                min2 = min1\n",
    "                min1 = i                \n",
    "            elif i < min2:\n",
    "                min2 = i\n",
    "            if i > max1:\n",
    "                max2 = max1\n",
    "                max1 = i\n",
    "            elif i > max2:\n",
    "                max2 = i\n",
    "        # print(min1,min2,max1,max2)\n",
    "        return (max1 * max2) - (min1 * min2)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maxProductDifference(self, nums: List[int]) -> int: \n",
    "        nums.sort()\n",
    "        return nums[-1]*nums[-2] - nums[0]*nums[1]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maxProductDifference(self, nums: List[int]) -> int:\n",
    "        nums.sort()\n",
    "\n",
    "        return nums[-1] * nums[-2] - nums[0] * nums[1]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maxProductDifference(self, nums: List[int]) -> int:\n",
    "        nums.sort()\n",
    "        return (nums[-1]*nums[-2])-(nums[0]*nums[1])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maxProductDifference(self, nums: List[int]) -> int:\n",
    "        sort_arr = sorted(nums)\n",
    "        max_v = sort_arr[-1] * sort_arr[-2]\n",
    "        min_v = sort_arr[0] * sort_arr[1]\n",
    "        return max_v - min_v"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maxProductDifference(self, nums: List[int]) -> int:\n",
    "        nums.sort()\n",
    "        return nums[-1] * nums[-2] - nums[0] *nums[1]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maxProductDifference(self, nums: List[int]) -> int:\n",
    "        nums.sort()\n",
    "        return (nums[-1]*nums[-2])-(nums[0]*nums[1])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maxProductDifference(self, nums: List[int]) -> int:\n",
    "        nums=sorted(nums);\n",
    "        return nums[-1]*nums[-2]-nums[0]*nums[1]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maxProductDifference(self, nums: List[int]) -> int:\n",
    "        nums.sort()\n",
    "        l = len(nums)\n",
    "        return (nums[l-1] * nums[l-2]) - (nums[0] * nums[1])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution(object):\n",
    "    def maxProductDifference(self, nums):\n",
    "        nums.sort()\n",
    "        return nums[-1] * nums[-2] - nums[0] * nums[1]        \n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maxProductDifference(self, nums: List[int]) -> int:\n",
    "        nums.sort()\n",
    "        return nums[-1] * nums[-2] - nums[0] * nums[1]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "\n",
    "\n",
    "class Solution:\n",
    "    def maxProductDifference(self, nums: List[int]) -> int:\n",
    "        nums.sort()\n",
    "        return nums[-1]*nums[-2]-nums[0]*nums[1]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maxProductDifference(self, nums: List[int]) -> int:\n",
    "        nums = sorted(nums)\n",
    "        return nums[-1]*nums[-2]-nums[1] * nums[0]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maxProductDifference(self, nums: List[int]) -> int:\n",
    "        nums = sorted(nums)\n",
    "\n",
    "        return nums[-1] * nums[-2] - nums[0] * nums[1]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maxProductDifference(self, nums: List[int]) -> int:\n",
    "        nums.sort()\n",
    "        n = len(nums)-1\n",
    "        return nums[n]*nums[n-1]-nums[0]*nums[1]\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maxProductDifference(self, nums: List[int]) -> int:\n",
    "        nums.sort()\n",
    "        return (nums[-1] * nums[-2] - nums[0] * nums[1])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maxProductDifference(self, nums: List[int]) -> int:\n",
    "        s1, s2, l2, l1 = sorted(nums[:4])  # 最小、次小、次大、最大\n",
    "        for x in range(4, len(nums)):\n",
    "            if nums[x] > l1: l1, l2 = nums[x], l1\n",
    "            elif nums[x] > l2: l2 = nums[x]\n",
    "            elif nums[x] < s1: s1, s2 = nums[x], s1\n",
    "            elif nums[x] < s2: s2 = nums[x]\n",
    "        return l2 * l1 - s1 * s2"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maxProductDifference(self, nums: List[int]) -> int:\n",
    "        a, b, c, d = 1, 0, 1, 0\n",
    "        if nums[a] < nums[b]:\n",
    "            a, b = b, a\n",
    "        if nums[c] > nums[d]:\n",
    "            c, d = d, c\n",
    "        for i in range(2, len(nums)):\n",
    "            if nums[i] > nums[c] and nums[i] > nums[d]:\n",
    "                c, d = d, i\n",
    "            elif nums[i] > nums[c]:\n",
    "                c = i\n",
    "            if nums[i] < nums[a] and nums[i] < nums[b]:\n",
    "                a, b = b, i\n",
    "            elif nums[i] < nums[a]:\n",
    "                a = i\n",
    "        return nums[c] * nums[d] - nums[a] * nums[b]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maxProductDifference(self, nums: List[int]) -> int:\n",
    "        nums.sort()\n",
    "        return (nums[-1] * nums[-2])  - (nums[0] * nums[1])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maxProductDifference(self, nums: List[int]) -> int:\n",
    "        nums.sort(reverse=False)\n",
    "        a = nums[-1]  *  nums[-2]\n",
    "        b = nums[0]  *  nums[1]\n",
    "        return a - b\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maxProductDifference(self, nums: List[int]) -> int:\n",
    "        n = len(nums)\n",
    "        mx1,mx2 = max(nums[0],nums[1]), min(nums[0],nums[1])\n",
    "        mn1,mn2 = min(nums[0],nums[1]), max(nums[0],nums[1])\n",
    "        for i in range(2,n):\n",
    "            tmp = nums[i]\n",
    "            if tmp>mx1:\n",
    "                mx1,mx2 = tmp,mx1\n",
    "            elif tmp>mx2:\n",
    "                mx2=tmp\n",
    "            if tmp<mn1:\n",
    "                mn1,mn2 = tmp,mn1\n",
    "            elif tmp<mn2:\n",
    "                mn2=tmp\n",
    "        return (mx1*mx2)-(mn1*mn2)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maxProductDifference(self, nums: List[int]) -> int:\n",
    "        nums.sort()\n",
    "        return (nums[-1] * nums[-2] - nums[0] * nums[1])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maxProductDifference(self, nums: List[int]) -> int:\n",
    "        a1=a2=0\n",
    "        b1=b2=0\n",
    "        a1=max(nums)\n",
    "        b1=min(nums)\n",
    "        print(a1,b1)\n",
    "        nums.remove(a1)\n",
    "        nums.remove(b1)\n",
    "        print(nums)\n",
    "        a2=max(nums)\n",
    "        b2=min(nums)\n",
    "        return (a1*a2)-(b1*b2)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maxProductDifference(self, nums: List[int]) -> int:\n",
    "        nt=sorted(nums)\n",
    "        return (nt[-1]*nt[-2]) - (nt[0]*nt[1])\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maxProductDifference(self, nums: List[int]) -> int:\n",
    "        # nums.sort()\n",
    "        # return nums[-1]*nums[-2] - nums[0]*nums[1]\n",
    "\n",
    "\n",
    "        n = len(nums)\n",
    "        # 数组中最大的两个值\n",
    "        mx1, mx2 = max(nums[0], nums[1]), min(nums[0], nums[1])\n",
    "        # 数组中最小的两个值\n",
    "        mn1, mn2 = min(nums[0], nums[1]), max(nums[0], nums[1])\n",
    "        for i in range(2, n):\n",
    "            tmp = nums[i]\n",
    "            if tmp > mx1:\n",
    "                mx1, mx2 = tmp, mx1\n",
    "            elif tmp > mx2:\n",
    "                mx2 = tmp\n",
    "            if tmp < mn1:\n",
    "                mn1, mn2 = tmp, mn1\n",
    "            elif tmp < mn2:\n",
    "                mn2 = tmp\n",
    "        return (mx1 * mx2) - (mn1 * mn2)\n",
    "\n",
    "# 作者：力扣官方题解\n",
    "# 链接：https://leetcode.cn/problems/maximum-product-difference-between-two-pairs/\n",
    "# 来源：力扣（LeetCode）\n",
    "# 著作权归作者所有。商业转载请联系作者获得授权，非商业转载请注明出处。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maxProductDifference(self, nums: List[int]) -> int:\n",
    "        nums.sort()\n",
    "        return (nums[-1] * nums[-2] - nums[0] * nums[1])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maxProductDifference(self, nums: List[int]) -> int:\n",
    "        a = max(nums)\n",
    "        nums.remove(a)\n",
    "        b = max(nums)\n",
    "        nums.remove(b)\n",
    "        c = min(nums)\n",
    "        nums.remove(c)\n",
    "        d = min(nums)\n",
    "        return a*b - c*d"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maxProductDifference(self, nums: List[int]) -> int:\n",
    "        max1, max2 = -1, -1\n",
    "        min1, min2 = 1e9, 1e9\n",
    "        for num in nums:\n",
    "            if num > max1:\n",
    "                max2 = max1\n",
    "                max1 = num\n",
    "            elif num > max2:\n",
    "                max2 = num\n",
    "            if num < min1:\n",
    "                min2 = min1\n",
    "                min1 = num\n",
    "            elif num < min2:\n",
    "                min2 = num\n",
    "        return max1 * max2 - min1 * min2"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maxProductDifference(self, nums: List[int]) -> int:\n",
    "        nums.sort()\n",
    "        return nums[-1]*nums[-2]-nums[0]*nums[1]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maxProductDifference(self, nums: List[int]) -> int:\n",
    "        nums.sort()\n",
    "        return (nums[-1]*nums[-2])-(nums[0]*nums[1])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maxProductDifference(self, nums: List[int]) -> int:\n",
    "        nums.sort()\n",
    "        return nums[-1]*nums[-2]-nums[0]*nums[1]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maxProductDifference(self, nums: List[int]) -> int:\n",
    "        nums = sorted(nums)\n",
    "        return (nums[-1] * nums[-2]) - (nums[0] * nums[1])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maxProductDifference(self, nums: List[int]) -> int:\n",
    "        da=[max(nums),0]\n",
    "        xiao=[min(nums),10000]\n",
    "        nums.remove(max(nums))\n",
    "        nums.remove(min(nums))\n",
    "        for i in nums:\n",
    "            if i>da[1]:\n",
    "                da[1]=i\n",
    "            if i<xiao[1]:\n",
    "                xiao[1]=i\n",
    "        return (da[0]*da[1]-xiao[0]*xiao[1])\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maxProductDifference(self, nums: List[int]) -> int:\n",
    "        a=max(nums)\n",
    "        b=min(nums)\n",
    "        nums.remove(a)\n",
    "        nums.remove(b)\n",
    "        c=max(nums)\n",
    "        d=min(nums)\n",
    "        return a*c-b*d"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maxProductDifference(self, nums: List[int]) -> int:\n",
    "        nums.sort()\n",
    "        return nums[-1] * nums[-2] - nums[0] * nums[1]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "'''\n",
    "class Solution:\n",
    "    def maxProductDifference(self, nums: List[int]) -> int:\n",
    "        nums.sort()\n",
    "        res = (nums[-1] * nums[-2]) - (nums[0] * nums[1])\n",
    "        return res \n",
    "'''\n",
    "\n",
    "class Solution:\n",
    "    def maxProductDifference(self, nums: List[int]) -> int:\n",
    "        a = max(nums)\n",
    "        nums.remove(a)\n",
    "        b = max(nums)\n",
    "        nums.remove(b)\n",
    "        c = min(nums)\n",
    "        nums.remove(c)\n",
    "        d = min(nums)\n",
    "\n",
    "        return (a*b) - (c*d)\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "# Definition for a binary tree node.\n",
    "# class TreeNode:\n",
    "#     def __init__(self, val=0, left=None, right=None):\n",
    "#         self.val = val\n",
    "#         self.left = left\n",
    "#         self.right = right\n",
    "class Solution:\n",
    "    def maxProduct(self, root: Optional[TreeNode]) -> int:\n",
    "        Mod = 10**9+7\n",
    "\n",
    "        def dfs(node):\n",
    "            if node is None:\n",
    "                return 0\n",
    "            node.val += dfs(node.left) + dfs(node.right)\n",
    "            return node.val\n",
    "        \n",
    "        dfs(root)\n",
    "\n",
    "        s = root.val\n",
    "        ans = 1\n",
    "        \n",
    "        def dfs2(node):\n",
    "            if node is None:\n",
    "                return\n",
    "            nonlocal ans\n",
    "            ans = max(ans, (s-node.val) * node.val)\n",
    "            dfs2(node.left)\n",
    "            dfs2(node.right)\n",
    "        \n",
    "        dfs2(root.left)\n",
    "        dfs2(root.right)\n",
    "\n",
    "        return ans % Mod"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "# Definition for a binary tree node.\n",
    "# class TreeNode:\n",
    "#     def __init__(self, val=0, left=None, right=None):\n",
    "#         self.val = val\n",
    "#         self.left = left\n",
    "#         self.right = right\n",
    "class Solution:\n",
    "    def maxProduct(self, root: Optional[TreeNode]) -> int:\n",
    "        def robot(node):\n",
    "            if not node:\n",
    "                return 0\n",
    "            lv = robot(node.left)\n",
    "            rv = robot(node.right)\n",
    "            node.val = lv + rv + node.val\n",
    "            return node.val\n",
    "        \n",
    "        s = robot(root)\n",
    "        base = 10 ** 9 + 7\n",
    "        ans = 0\n",
    "        def dfs(node):\n",
    "            if not node:\n",
    "                return\n",
    "            dfs(node.left)\n",
    "            nonlocal ans\n",
    "            ans = max(ans, node.val * (s - node.val))\n",
    "            # ans = max(ans, ((node.val % base) * ((s - node.val) % base)) % base)\n",
    "            dfs(node.right)\n",
    "        dfs(root)\n",
    "        return ans % base\n",
    "            \n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "# Definition for a binary tree node.\n",
    "# class TreeNode:\n",
    "#     def __init__(self, val=0, left=None, right=None):\n",
    "#         self.val = val\n",
    "#         self.left = left\n",
    "#         self.right = right\n",
    "class Solution:\n",
    "    def maxProduct(self, root: Optional[TreeNode]) -> int:\n",
    "        weight_list = []\n",
    "        self.dfs(root, weight_list)\n",
    "        res = 0\n",
    "        for weight in weight_list:\n",
    "            res = max(res, (weight_list[-1] - weight) * weight)\n",
    "        \n",
    "        return res % (10 ** 9 + 7)\n",
    "    \n",
    "    def dfs(self, now, weight_list):\n",
    "        weight = now.val\n",
    "        if now.left:\n",
    "            weight += self.dfs(now.left, weight_list)\n",
    "        if now.right:\n",
    "            weight += self.dfs(now.right, weight_list)\n",
    "        \n",
    "        weight_list.append(weight)\n",
    "        return weight"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "# Definition for a binary tree node.\n",
    "# class TreeNode:\n",
    "#     def __init__(self, val=0, left=None, right=None):\n",
    "#         self.val = val\n",
    "#         self.left = left\n",
    "#         self.right = right\n",
    "class Solution:\n",
    "    def maxProduct(self, root: TreeNode) -> int:\n",
    "        list_sum = []\n",
    "\n",
    "        def dfs(node):\n",
    "            if not node: return 0\n",
    "            sum = dfs(node.left) + dfs(node.right) + node.val\n",
    "            list_sum.append(sum)\n",
    "            return sum\n",
    "\n",
    "        total = dfs(root)\n",
    "        ans = float('-inf')\n",
    "        for sum in list_sum:\n",
    "            ans = max(ans, sum*(total-sum))\n",
    "\n",
    "        return ans % (10**9+7)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "# Definition for a binary tree node.\n",
    "# class TreeNode:\n",
    "#     def __init__(self, val=0, left=None, right=None):\n",
    "#         self.val = val\n",
    "#         self.left = left\n",
    "#         self.right = right\n",
    "class Solution:\n",
    "    def __init__(self):\n",
    "        self.res = 0\n",
    "        self.sum = 0\n",
    "\n",
    "    def maxProduct(self, root: Optional[TreeNode]) -> int:\n",
    "        self.sum_node(root)\n",
    "        self.traverse(root)\n",
    "        return self.res % (10 ** 9 + 7)\n",
    "\n",
    "    def sum_node(self, root):\n",
    "        if not root:\n",
    "            return\n",
    "        self.sum_node(root.left)\n",
    "        self.sum_node(root.right)\n",
    "        self.sum += root.val\n",
    "\n",
    "    def traverse(self, root):\n",
    "        if not root:\n",
    "            return\n",
    "        left = self.traverse(root.left)\n",
    "        right = self.traverse(root.right)\n",
    "        left = left if left else 0\n",
    "        right = right if right else 0\n",
    "        self.res = max(self.res, right * (self.sum - right), left * (self.sum - left))\n",
    "        return root.val + left + right\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "# Definition for a binary tree node.\n",
    "# class TreeNode:\n",
    "#     def __init__(self, val=0, left=None, right=None):\n",
    "#         self.val = val\n",
    "#         self.left = left\n",
    "#         self.right = right\n",
    "class Solution:\n",
    "    def __init__(self):\n",
    "        self.res = 0\n",
    "        self.sum = 0\n",
    "\n",
    "    def maxProduct(self, root: Optional[TreeNode]) -> int:\n",
    "        self.sum_node(root)\n",
    "        self.traverse(root)\n",
    "        return self.res % (10 ** 9 + 7)\n",
    "\n",
    "    def sum_node(self, root):\n",
    "        if not root:\n",
    "            return\n",
    "        self.sum_node(root.left)\n",
    "        self.sum_node(root.right)\n",
    "        self.sum += root.val\n",
    "\n",
    "    def traverse(self, root):\n",
    "        if not root:\n",
    "            return\n",
    "        left = self.traverse(root.left)\n",
    "        right = self.traverse(root.right)\n",
    "        left = left if left else 0\n",
    "        right = right if right else 0\n",
    "        self.res = max(self.res, right * (self.sum - right), left * (self.sum - left))\n",
    "        return root.val + left + right\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "# Definition for a binary tree node.\n",
    "# class TreeNode:\n",
    "#     def __init__(self, val=0, left=None, right=None):\n",
    "#         self.val = val\n",
    "#         self.left = left\n",
    "#         self.right = right\n",
    "class Solution:\n",
    "    # def get_sum(self, root):\n",
    "    #     if root is None:\n",
    "    #         return 0\n",
    "    #     return root.val + self.get_sum(root.left) + self.get_sum(root.right)\n",
    "\n",
    "    # def get_split_max(self, node, tree_sum):\n",
    "    #     if node is None:\n",
    "    #         return 0\n",
    "    #     left = self.get_sum(node.left)\n",
    "    #     right = self.get_sum(node.right)\n",
    "    #     return max((tree_sum - left) * left, (tree_sum - right) * right)\n",
    "\n",
    "    # def maxProduct(self, root: Optional[TreeNode]) -> int:\n",
    "    #     tree_sum = self.get_sum(root)\n",
    "    #     res = 0 if root is None else root.val\n",
    "    #     queue = [root]\n",
    "    #     while queue:\n",
    "    #         node = queue.pop(0)\n",
    "    #         res = max(res, self.get_split_max(node, tree_sum))\n",
    "    #         if node.left:\n",
    "    #             queue.append(node.left)\n",
    "    #         if node.right:\n",
    "    #             queue.append(node.right)\n",
    "    #     return res % 1000000007\n",
    "\n",
    "    def get_sum(self, root, sum_list):\n",
    "        if root is None:\n",
    "            return 0\n",
    "        left = self.get_sum(root.left, sum_list)\n",
    "        right = self.get_sum(root.right, sum_list)\n",
    "        res = root.val + left + right\n",
    "        sum_list.append(res)\n",
    "        return res\n",
    "\n",
    "    def maxProduct(self, root: Optional[TreeNode]) -> int:\n",
    "        if root is None:\n",
    "            return 0\n",
    "        sum_list = []\n",
    "        self.get_sum(root, sum_list)\n",
    "        tree_sum = sum_list[-1]\n",
    "        res = sum_list[0] * (tree_sum - sum_list[0])\n",
    "        for i in range(1, len(sum_list) - 1):\n",
    "            res = max(res, sum_list[i] * (tree_sum - sum_list[i]))\n",
    "        return res % 1000000007\n",
    "        # tree_sum = self.get_sum(root)\n",
    "        # res = 0 if root is None else root.val\n",
    "        # queue = [root]\n",
    "        # while queue:\n",
    "        #     node = queue.pop(0)\n",
    "        #     res = max(res, self.get_split_max(node, tree_sum))\n",
    "        #     if node.left:\n",
    "        #         queue.append(node.left)\n",
    "        #     if node.right:\n",
    "        #         queue.append(node.right)\n",
    "        # return res % 1000000007\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "# Definition for a binary tree node.\n",
    "# class TreeNode:\n",
    "#     def __init__(self, val=0, left=None, right=None):\n",
    "#         self.val = val\n",
    "#         self.left = left\n",
    "#         self.right = right\n",
    "class Solution:\n",
    "    # 所谓的分裂二叉树，是指把二叉树任意一个子树和其他部分分离开。\n",
    "    # 求子树的和，不是求节点的和\n",
    "    def maxProduct(self, root: Optional[TreeNode]) -> int:\n",
    "        self.sums = []\n",
    "        self.get_sum(root)\n",
    "        sum_ = max(self.sums)\n",
    "        res = 1\n",
    "        for x in self.sums:\n",
    "            res = max(res, x*(sum_-x))\n",
    "        return res % (10**9 + 7)\n",
    "        \n",
    "    \n",
    "    def get_sum(self, root):\n",
    "        if not root: return 0   # return 不一定None\n",
    "        sum_ = root.val + self.get_sum(root.left) + self.get_sum(root.right)\n",
    "        self.sums.append(sum_)\n",
    "        return sum_"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "from typing import List\n",
    "# Definition for a binary tree node.\n",
    "# class TreeNode:\n",
    "#     def __init__(self, val=0, left=None, right=None):\n",
    "#         self.val = val\n",
    "#         self.left = left\n",
    "#         self.right = right\n",
    "class Solution:\n",
    "    def maxProduct(self, root: Optional[TreeNode]) -> int:\n",
    "        def get_sum_all(node):\n",
    "            if not node:\n",
    "                return\n",
    "            nonlocal sum_all\n",
    "            sum_all += node.val\n",
    "            get_sum_all(node.left)\n",
    "            get_sum_all(node.right)\n",
    "        sum_all = 0\n",
    "        get_sum_all(root)\n",
    "        ans = float('-inf')\n",
    "        def dfs(node):\n",
    "            if not node:\n",
    "                return 0\n",
    "            left = dfs(node.left)\n",
    "            right = dfs(node.right)\n",
    "            submax = left + node.val + right\n",
    "            nonlocal ans\n",
    "            ans = max(ans, submax * (sum_all - submax))\n",
    "            return submax\n",
    "        dfs(root)\n",
    "      \n",
    "        return ans % (10**9+7)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "# Definition for a binary tree node.\n",
    "# class TreeNode:\n",
    "#     def __init__(self, val=0, left=None, right=None):\n",
    "#         self.val = val\n",
    "#         self.left = left\n",
    "#         self.right = right\n",
    "class Solution:\n",
    "    ls=[]\n",
    "\n",
    "    def maxProduct(self, root: Optional[TreeNode]) -> int:\n",
    "        self.ls=[]\n",
    "        Solution.get_sum(self,root)\n",
    "        \n",
    "        sum=self.ls[-1]\n",
    "        temp=0\n",
    "        for i in range(len(self.ls)-2,-1,-1):\n",
    "            temp1=self.ls[i]*(sum-self.ls[i])\n",
    "            if temp1>temp:\n",
    "                temp=temp1\n",
    "        return temp%(10**9+7)\n",
    "\n",
    "       \n",
    "\n",
    "        \n",
    "        \n",
    "\n",
    "\n",
    "    def get_sum(self,root):\n",
    "        if root==None:\n",
    "            return 0\n",
    "        sum=root.val+Solution.get_sum(self,root.left)+Solution.get_sum(self,root.right)\n",
    "        self.ls.append(sum)\n",
    "        return sum\n",
    "\n",
    "        \n",
    "\n",
    "   \n",
    "\n",
    "        "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "# Definition for a binary tree node.\n",
    "# class TreeNode:\n",
    "#     def __init__(self, val=0, left=None, right=None):\n",
    "#         self.val = val\n",
    "#         self.left = left\n",
    "#         self.right = right\n",
    "class Solution:\n",
    "    def maxProduct(self, root: Optional[TreeNode]) -> int:\n",
    "\n",
    "        def getSum(node):\n",
    "            if not node:\n",
    "                return 0\n",
    "            return node.val + getSum(node.left) + getSum(node.right)\n",
    "        \n",
    "        s = getSum(root)\n",
    "        res = 0\n",
    "\n",
    "        def dfs(node):\n",
    "            if not node:\n",
    "                return 0\n",
    "            \n",
    "            nonlocal res\n",
    "            subsum = node.val + dfs(node.left) + dfs(node.right)\n",
    "            res = max(res, subsum*(s-subsum))\n",
    "            return subsum\n",
    "        \n",
    "        dfs(root)\n",
    "        return res % (10**9+7)\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "# Definition for a binary tree node.\n",
    "# class TreeNode:\n",
    "#     def __init__(self, val=0, left=None, right=None):\n",
    "#         self.val = val\n",
    "#         self.left = left\n",
    "#         self.right = right\n",
    "class Solution:\n",
    "    def maxProduct(self, root: Optional[TreeNode]) -> int:\n",
    "        res = []\n",
    "        def dfs(node ):\n",
    "            if node is None :\n",
    "                return 0 \n",
    "            sum2 = node.val + dfs(node.left) + dfs(node.right)  #对二叉树进行求和\n",
    "            res.append(sum2)\n",
    "            return sum2 \n",
    "        dfs(root)  \n",
    "        root_sum = res[-1]\n",
    "        max_sum =0\n",
    "        for i in res:\n",
    "            max_sum = max(i * (root_sum - i) ,max_sum)\n",
    "        return (max_sum % (10**9 +7))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "# Definition for a binary tree node.\n",
    "# class TreeNode:\n",
    "#     def __init__(self, val=0, left=None, right=None):\n",
    "#         self.val = val\n",
    "#         self.left = left\n",
    "#         self.right = right\n",
    "class Solution:\n",
    "    def helper(self,root):\n",
    "        if not root:\n",
    "            return 0\n",
    "        else:\n",
    "            a=root.val\n",
    "            a+=self.helper(root.left)\n",
    "            a+=self.helper(root.right)\n",
    "            return a\n",
    "    def helper2(self,root,sum):\n",
    "        if not root:\n",
    "            return 0,sum\n",
    "        else:\n",
    "            a=root.val\n",
    "            a1,b1=self.helper2(root.left,sum)\n",
    "            a2,b2=self.helper2(root.right,sum)\n",
    "            a+=a1+a2\n",
    "            return a,min(abs(a-sum/2),b1,b2)\n",
    "\n",
    "    def maxProduct(self, root: Optional[TreeNode]) -> int:\n",
    "        mod=10**9+7\n",
    "        sum=self.helper(root)\n",
    "        _,close=self.helper2(root,sum)\n",
    "        a=round(sum/2+close)\n",
    "        b=sum-a\n",
    "        return a*b%mod\n",
    "\n",
    "\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "# Definition for a binary tree node.\n",
    "# class TreeNode:\n",
    "#     def __init__(self, val=0, left=None, right=None):\n",
    "#         self.val = val\n",
    "#         self.left = left\n",
    "#         self.right = right\n",
    "class Solution:\n",
    "    def maxProduct(self, root: Optional[TreeNode]) -> int:\n",
    "        # ls = []\n",
    "        # def dfs(root):\n",
    "        #     if not root: return 0\n",
    "        #     s = root.val + dfs(root.left) + dfs(root.right)\n",
    "        #     ls.append(s)\n",
    "        #     return s\n",
    "        # dfs(root)\n",
    "        # ans = 0\n",
    "        # ts = ls[-1]\n",
    "        # for ss in ls:\n",
    "        #     if abs(2*ss-ts) < abs(2*ans-ts):\n",
    "        #         ans = ss\n",
    "        # return ans * (ts-ans) % (10**9+7)\n",
    "\n",
    "\n",
    "\n",
    "        s = []\n",
    "        def dfs(cur: Optional[TreeNode]) -> int:\n",
    "            if not cur:\n",
    "                return 0\n",
    "            s.append(total := dfs(cur.left) + cur.val + dfs(cur.right))\n",
    "            return total\n",
    "        total = dfs(root)\n",
    "        return max(i * (total - i) for i in s) % (10 ** 9 + 7)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "MOD = 10 ** 9 + 7\n",
    "class Solution:\n",
    "    def maxProduct(self, root: Optional[TreeNode]) -> int:\n",
    "        # 获得所有子树的和，和所有节点的和，寻找与节点和的一半最接近的子树和\n",
    "        subtotal = []\n",
    "        total = 0\n",
    "        def dfs(node):\n",
    "            if not node:\n",
    "                return 0\n",
    "            cur_total = node.val + dfs(node.left) + dfs(node.right)\n",
    "            subtotal.append(cur_total)\n",
    "            nonlocal total\n",
    "            total += node.val\n",
    "            return cur_total\n",
    "        \n",
    "        dfs(root)\n",
    "        target = total / 2\n",
    "        closest = min(subtotal, key=lambda x:abs(x - target))\n",
    "        return closest * (total - closest) % MOD"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "# Definition for a binary tree node.\n",
    "# class TreeNode:\n",
    "#     def __init__(self, val=0, left=None, right=None):\n",
    "#         self.val = val\n",
    "#         self.left = left\n",
    "#         self.right = right\n",
    "class Solution:\n",
    "\n",
    "    \n",
    "    def maxProduct(self, root: Optional[TreeNode]) -> int:\n",
    "        \n",
    "        if not root:\n",
    "            return 0\n",
    "        self.node_sum_map = set()\n",
    "        def dfs(root):\n",
    "            if not root:\n",
    "                return 0\n",
    "            res = root.val + dfs(root.left) + dfs(root.right)\n",
    "            self.node_sum_map.add(res)\n",
    "            return res\n",
    "\n",
    "        node_sum = dfs(root)\n",
    "        res = 0\n",
    "        for value in self.node_sum_map:\n",
    "            # print(key.val, value)\n",
    "            res = max(res, value*(node_sum-value ))\n",
    "        return res % (10**9 + 7)\n",
    "    "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "# Definition for a binary tree node.\n",
    "# class TreeNode:\n",
    "#     def __init__(self, val=0, left=None, right=None):\n",
    "#         self.val = val\n",
    "#         self.left = left\n",
    "#         self.right = right\n",
    "class Solution:\n",
    "\n",
    "    \n",
    "\n",
    "    def maxProduct(self, root: Optional[TreeNode]) -> int:\n",
    "        if not root:\n",
    "            return 0\n",
    "        self.node_sum_map = set()\n",
    "        def dfs(root):\n",
    "            if not root:\n",
    "                return 0\n",
    "            res = root.val + dfs(root.left) + dfs(root.right)\n",
    "            self.node_sum_map.add(res)\n",
    "            return res\n",
    "\n",
    "        node_sum = dfs(root)\n",
    "        res = 0\n",
    "        for value in self.node_sum_map:\n",
    "            # print(key.val, value)\n",
    "            res = max(res, value*(node_sum-value ))\n",
    "        return res % (10**9 + 7)\n",
    "    "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "from sortedcontainers import SortedList\n",
    "# Definition for a binary tree node.\n",
    "# class TreeNode:\n",
    "#     def __init__(self, val=0, left=None, right=None):\n",
    "#         self.val = val\n",
    "#         self.left = left\n",
    "#         self.right = right\n",
    "class Solution:\n",
    "    def maxProduct(self, root: Optional[TreeNode]) -> int:\n",
    "        arr = set()\n",
    "        \n",
    "        def dfs(node):\n",
    "            if not node:\n",
    "                return 0\n",
    "            ret = node.val + dfs(node.left) + dfs(node.right)\n",
    "            arr.add(ret)\n",
    "            return ret\n",
    "\n",
    "        dfs(root)\n",
    "        arr = sorted(arr)\n",
    "        s = arr[-1]\n",
    "        idx = bisect_right(arr, (s + 1) // 2)\n",
    "        ans1 = ans2 = 0\n",
    "        if idx > 0: \n",
    "            ans1 = (s - arr[idx - 1]) * arr[idx - 1]\n",
    "        if idx < len(arr):  \n",
    "            ans2 = (s - arr[idx]) * arr[idx]\n",
    "        return max(ans1, ans2) % (10 ** 9 + 7)\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "# Definition for a binary tree node.\n",
    "# class TreeNode:\n",
    "#     def __init__(self, val=0, left=None, right=None):\n",
    "#         self.val = val\n",
    "#         self.left = left\n",
    "#         self.right = right\n",
    "class Solution:\n",
    "    def maxProduct(self, root: Optional[TreeNode]) -> int:\n",
    "        collect = set()\n",
    "        \n",
    "        def total(node) -> int:\n",
    "            if not node:\n",
    "                return 0\n",
    "            \n",
    "            tot = node.val + total(node.left) + total(node.right)\n",
    "            collect.add(tot)\n",
    "            return tot\n",
    "        \n",
    "        tot = total(root)\n",
    "        mx = 0\n",
    "        for sub in collect:\n",
    "            mx = max(mx, 1.0 * sub * (tot - sub))\n",
    "        \n",
    "        return int(mx % (10**9 + 7))\n",
    "        "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "# Definition for a binary tree node.\n",
    "# class TreeNode:\n",
    "#     def __init__(self, val=0, left=None, right=None):\n",
    "#         self.val = val\n",
    "#         self.left = left\n",
    "#         self.right = right\n",
    "class Solution:\n",
    "    def maxProduct(self, root: Optional[TreeNode]) -> int:\n",
    "        collect = set()\n",
    "        \n",
    "        def total(node) -> int:\n",
    "            if not node:\n",
    "                return 0\n",
    "            \n",
    "            tot = node.val + total(node.left) + total(node.right)\n",
    "            collect.add(tot)\n",
    "            return tot\n",
    "        \n",
    "        tot = total(root)\n",
    "        mx = 0\n",
    "        for sub in collect:\n",
    "            mx = max(mx, sub * (tot - sub))\n",
    "        \n",
    "        return mx % (10**9 + 7)\n",
    "        "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "# Definition for a binary tree node.\n",
    "# class TreeNode:\n",
    "#     def __init__(self, val=0, left=None, right=None):\n",
    "#         self.val = val\n",
    "#         self.left = left\n",
    "#         self.right = right\n",
    "class Solution:\n",
    "    def maxProduct(self, root: Optional[TreeNode]) -> int:\n",
    "        hashmap = {}\n",
    "        def dfs(root):\n",
    "            if not root:\n",
    "                return 0\n",
    "            left = dfs(root.left)\n",
    "            right = dfs(root.right)\n",
    "            hashmap[root] = left + right + root.val\n",
    "            return left + right + root.val\n",
    "        dfs(root)\n",
    "        res = 0\n",
    "        for v in hashmap.values():\n",
    "            res = max(res, (v*(hashmap[root] - v)))\n",
    "        return res % (10**9 + 7)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "# Definition for a binary tree node.\n",
    "# class TreeNode:\n",
    "#     def __init__(self, val=0, left=None, right=None):\n",
    "#         self.val = val\n",
    "#         self.left = left\n",
    "#         self.right = right\n",
    "class Solution:\n",
    "\n",
    "    \n",
    "\n",
    "    def maxProduct(self, root: Optional[TreeNode]) -> int:\n",
    "        # Input -> root \n",
    "        # Positive values, not 0 \n",
    "\n",
    "        # Break all edges and calculate the product and pick the largest one\n",
    "        # E * DFS O(N+E)\n",
    "\n",
    "        # so the max product happens when the split make the sum as close as possible \n",
    "        # find the sum of each node of their children\n",
    "\n",
    "        if not root: \n",
    "            return 0\n",
    "\n",
    "        self.sumDict = {}\n",
    "        def treeValSum(node) -> int:\n",
    "            if not node:\n",
    "                return 0\n",
    "            left = treeValSum(node.left) if node.left else 0\n",
    "            right = treeValSum(node.right) if node.right else 0\n",
    "            s = node.val + left + right\n",
    "            self.sumDict[node] = s\n",
    "            return s\n",
    "        \n",
    "        totalSum = treeValSum(root)\n",
    "\n",
    "        maxProduct = 0\n",
    "        for val in self.sumDict.values():\n",
    "            maxProduct = max(maxProduct, (totalSum - val) * val)\n",
    "        \n",
    "        return maxProduct % (10**9+7)\n",
    "    \n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "# Definition for a binary tree node.\n",
    "# class TreeNode:\n",
    "#     def __init__(self, val=0, left=None, right=None):\n",
    "#         self.val = val\n",
    "#         self.left = left\n",
    "#         self.right = right\n",
    "class Solution:\n",
    "    def maxProduct(self, root: Optional[TreeNode]) -> int:\n",
    "        mod = 10 ** 9 + 7\n",
    "        d = defaultdict(int)\n",
    "        def dfs(root):\n",
    "            if not root:\n",
    "                return 0\n",
    "            lv = dfs(root.left)\n",
    "            rv = dfs(root.right)\n",
    "            cur = root.val + lv + rv\n",
    "            d[root] = cur\n",
    "            return cur\n",
    "            \n",
    "        dfs(root)\n",
    "        tot = d[root] \n",
    "        ans = tot\n",
    "        best = -1\n",
    "        q = deque([root])\n",
    "        while q:\n",
    "            cur = q.popleft()\n",
    "            if abs((tot - d[cur]) - d[cur]) < ans:\n",
    "                best = d[cur]\n",
    "                ans = abs((tot - d[cur]) - d[cur])\n",
    "            if cur.left:\n",
    "                q.append(cur.left)\n",
    "            if cur.right:\n",
    "                q.append(cur.right)\n",
    "\n",
    "        return best * (tot - best) % mod"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "# Definition for a binary tree node.\n",
    "# class TreeNode:\n",
    "#     def __init__(self, val=0, left=None, right=None):\n",
    "#         self.val = val\n",
    "#         self.left = left\n",
    "#         self.right = right\n",
    "class Solution:\n",
    "    def __init__(self):\n",
    "        self.node_sum_map = {}\n",
    "    def dfs(self, root):\n",
    "        if root in self.node_sum_map:\n",
    "            return self.node_sum_map[root]\n",
    "        if not root:\n",
    "            return 0\n",
    "        res = root.val + self.dfs(root.left) + self.dfs(root.right)\n",
    "        self.node_sum_map[root] = res\n",
    "        return res\n",
    "\n",
    "    def maxProduct(self, root: Optional[TreeNode]) -> int:\n",
    "        node_sum = self.dfs(root)\n",
    "        print(node_sum)\n",
    "        res = 0\n",
    "        for key, value in self.node_sum_map.items():\n",
    "            # print(key.val, value)\n",
    "            res = max(res, value*(node_sum-value ))\n",
    "        return res % (10**9 + 7)\n",
    "    "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "# Definition for a binary tree node.\n",
    "# class TreeNode:\n",
    "#     def __init__(self, val=0, left=None, right=None):\n",
    "#         self.val = val\n",
    "#         self.left = left\n",
    "#         self.right = right\n",
    "class Solution:\n",
    "    def maxProduct(self, root: Optional[TreeNode]) -> int:\n",
    "        # 枚举除根节点外所有节点为其中一颗子树的根节点即可\n",
    "        def dfs(cur):\n",
    "            if not cur:return 0\n",
    "            cursum=cur.val \n",
    "            cursum+=dfs(cur.left)\n",
    "            cursum+=dfs(cur.right)\n",
    "            hashmap[cur]=cursum\n",
    "            return cursum \n",
    "        hashmap={}\n",
    "        dfs(root)\n",
    "        total=hashmap[root]\n",
    "        Mod=10**9+7\n",
    "        res=0\n",
    "        for key in hashmap:\n",
    "            res=max(res,(total-hashmap[key])*hashmap[key])\n",
    "        return res%Mod"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "from collections import defaultdict\n",
    "# Definition for a binary tree node.\n",
    "# class TreeNode:\n",
    "#     def __init__(self, val=0, left=None, right=None):\n",
    "#         self.val = val\n",
    "#         self.left = left\n",
    "#         self.right = right\n",
    "class Solution:\n",
    "    def maxProduct(self, root: Optional[TreeNode]) -> int:\n",
    "        MOD = 10**9+7\n",
    "        childSum = defaultdict(int)\n",
    "        ret = 0\n",
    "        def dfsSum(node: TreeNode) -> None:\n",
    "            childSum[node] = node.val\n",
    "            if node.left:\n",
    "                dfsSum(node.left)\n",
    "                childSum[node] += childSum[node.left]\n",
    "            if node.right:\n",
    "                dfsSum(node.right)\n",
    "                childSum[node] += childSum[node.right]\n",
    "        def dfsMaxProduct(node: TreeNode) -> None:\n",
    "            nonlocal ret\n",
    "            if not node:\n",
    "                return\n",
    "            if node.left:\n",
    "                ret = max(ret, (childSum[root] - childSum[node.left]) * childSum[node.left])\n",
    "                dfsMaxProduct(node.left)\n",
    "            if node.right:\n",
    "                ret = max(ret, (childSum[root] - childSum[node.right]) * childSum[node.right])\n",
    "                dfsMaxProduct(node.right)\n",
    "        dfsSum(root)\n",
    "        dfsMaxProduct(root)\n",
    "        return ret % MOD"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "# Definition for a binary tree node.\n",
    "# class TreeNode:\n",
    "#     def __init__(self, val=0, left=None, right=None):\n",
    "#         self.val = val\n",
    "#         self.left = left\n",
    "#         self.right = right\n",
    "from typing import Optional\n",
    "\n",
    "\n",
    "class Solution:\n",
    "    def maxProduct(self, root: Optional[TreeNode]) -> int:\n",
    "        ans = -float('inf')\n",
    "        # 层次法重建二叉树的值\n",
    "        def bfs(root):\n",
    "            levelmap = {}\n",
    "            if root is None:\n",
    "                return levelmap\n",
    "            level = 1\n",
    "            queue = [root]\n",
    "            while queue:\n",
    "                stack = []\n",
    "                while queue:\n",
    "                    stack.append(queue.pop(0))\n",
    "                while stack:\n",
    "                    if level not in levelmap.keys():\n",
    "                        levelmap[level] = []\n",
    "                    node = stack.pop(0)\n",
    "                    levelmap[level].append(node)\n",
    "                    if node.left is not None:\n",
    "                        queue.append(node.left)\n",
    "                    if node.right is not None:\n",
    "                        queue.append(node.right)\n",
    "                level += 1\n",
    "            # 从下往上对每个元素进行节点求和\n",
    "            level -= 2\n",
    "            while level > 0:\n",
    "                for node in levelmap[level]:\n",
    "                    if node.left is not None:\n",
    "                        node.val += node.left.val\n",
    "                    if node.right is not None:\n",
    "                        node.val += node.right.val\n",
    "                level -= 1\n",
    "\n",
    "        # 递归求最大值: (total - 子树和) * 子树和\n",
    "        def comp(root, total=0):\n",
    "            if root is None:\n",
    "                return 0\n",
    "            nonlocal ans\n",
    "            a1 = 0\n",
    "            if root.left is not None:\n",
    "                a1 = root.left.val * (total - root.left.val)\n",
    "            a2 = 0\n",
    "            if root.right is not None:\n",
    "                a2 = root.right.val * (total - root.right.val)\n",
    "            ans = max(ans, a1, a2)\n",
    "            comp(root.left, total)\n",
    "            comp(root.right, total)\n",
    "\n",
    "        # 开始计算\n",
    "        bfs(root)\n",
    "        comp(root, root.val)\n",
    "\n",
    "        return ans % (10**9+7)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "# Definition for a binary tree node.\n",
    "# class TreeNode:\n",
    "#     def __init__(self, val=0, left=None, right=None):\n",
    "#         self.val = val\n",
    "#         self.left = left\n",
    "#         self.right = right\n",
    "class Solution:\n",
    "    def maxProduct(self, root: Optional[TreeNode]) -> int:\n",
    "        sum_set = set()\n",
    "        \n",
    "        def dfs(node):\n",
    "            if not node:\n",
    "                sum_set.add(0)\n",
    "                return 0\n",
    "            left = dfs(node.left)\n",
    "            right = dfs(node.right)\n",
    "            total = node.val + left + right\n",
    "            sum_set.add(total)\n",
    "            return total\n",
    "        \n",
    "        total = dfs(root)\n",
    "        ans = 0\n",
    "        for subTree_sum in sum_set:\n",
    "            ans = max(ans, (total - subTree_sum) * subTree_sum)\n",
    "        return ans % (10 ** 9 + 7)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "# Definition for a binary tree node.\n",
    "# class TreeNode:\n",
    "#     def __init__(self, val=0, left=None, right=None):\n",
    "#         self.val = val\n",
    "#         self.left = left\n",
    "#         self.right = right\n",
    "class Solution:\n",
    "    def maxProduct(self, root: Optional[TreeNode]) -> int:\n",
    "        self.res = 0\n",
    "        self.leftsum = {}\n",
    "        self.rightsum = {}\n",
    "        def getsum(root):\n",
    "            if root is None:\n",
    "                return 0\n",
    "            \n",
    "            left = getsum(root.left)\n",
    "            right = getsum(root.right)\n",
    "            self.leftsum[root]=left\n",
    "            self.rightsum[root] = right\n",
    "            return left+right+root.val\n",
    "        getsum(root)\n",
    "\n",
    "        def dfs(root,pval):\n",
    "            if root is None:\n",
    "                return 0\n",
    "            \n",
    "            self.res = max(self.res,pval*(root.val+self.rightsum[root]+self.leftsum[root]))\n",
    "            dfs(root.left,root.val+pval+self.rightsum[root])\n",
    "            dfs(root.right,root.val+pval+self.leftsum[root])\n",
    "        dfs(root,0)\n",
    "        return self.res % (10**9+7)\n",
    "            "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "# Definition for a binary tree node.\n",
    "# class TreeNode:\n",
    "#     def __init__(self, val=0, left=None, right=None):\n",
    "#         self.val = val\n",
    "#         self.left = left\n",
    "#         self.right = right\n",
    "class Solution:\n",
    "    def maxProduct(self, root: TreeNode) -> int:\n",
    "        def digui(node):\n",
    "            if not node:\n",
    "                return 0\n",
    "            return node.val + digui(node.left) + digui(node.right)\n",
    "        the_sum = digui(root)\n",
    "        def digui2(node, t_sum):\n",
    "            if not node:\n",
    "                return 0, 0\n",
    "            left_sum, left_r = digui2(node.left, t_sum)\n",
    "            right_sum, right_r = digui2(node.right, t_sum)\n",
    "            this_sum = left_sum+right_sum+node.val\n",
    "            res = max(left_r, right_r, this_sum*(t_sum-this_sum))\n",
    "            return this_sum, res\n",
    "        _, result = digui2(root, the_sum)\n",
    "        return int(result % (1e9+7))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "# Definition for a binary tree node.\n",
    "# class TreeNode:\n",
    "#     def __init__(self, x):\n",
    "#         self.val = x\n",
    "#         self.left = None\n",
    "#         self.right = None\n",
    "\n",
    "class Solution:\n",
    "    def maxProduct(self, root: TreeNode) -> int:\n",
    "\n",
    "        def getTot(root):\n",
    "            if not root:\n",
    "                return []\n",
    "\n",
    "            tots = []\n",
    "            totLmax = 0\n",
    "            totRmax = 0\n",
    "            if root.left:\n",
    "                totL = getTot(root.left)\n",
    "                totLmax = totL[-1]\n",
    "                tots += totL\n",
    "            if root.right:\n",
    "                totR = getTot(root.right)\n",
    "                totRmax = totR[-1]\n",
    "                tots += totR\n",
    "            \n",
    "            tots.append(totLmax + totRmax + root.val)\n",
    "            return tots\n",
    "\n",
    "        tots = getTot(root)\n",
    "        tot = tots[-1]\n",
    "        minD = tot\n",
    "        for i in tots:\n",
    "            if abs(i - tot / 2) < minD:\n",
    "                minD = abs(i - tot/2)\n",
    "        pro = (tot / 2) **2 - minD**2\n",
    "        return int(pro) % (10**9 + 7)\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "# Definition for a binary tree node.\n",
    "# class TreeNode:\n",
    "#     def __init__(self, val=0, left=None, right=None):\n",
    "#         self.val = val\n",
    "#         self.left = left\n",
    "#         self.right = right\n",
    "class Solution:\n",
    "    def maxProduct(self, root: TreeNode) -> int:\n",
    "        MOD, self.res = 1000000007, 0\n",
    "        def dfs(node):\n",
    "            if not node: return 0\n",
    "            node.leftsm = dfs(node.left)\n",
    "            node.rightsm = dfs(node.right)\n",
    "            return node.leftsm + node.val + node.rightsm\n",
    "\n",
    "        def dfs2(node, sm):\n",
    "            if node and (node.left or node.right):\n",
    "                lsm, rsm, v = node.leftsm, node.rightsm, node.val\n",
    "                lalsm, ralsm = rsm + v + sm, lsm + v + sm\n",
    "                self.res = max(self.res, lsm*lalsm, rsm*ralsm)\n",
    "                dfs2(node.left, lalsm)\n",
    "                dfs2(node.right, ralsm)\n",
    "\n",
    "        dfs(root)\n",
    "        dfs2(root, 0)\n",
    "        return self.res % MOD\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "# Definition for a binary tree node.\n",
    "# class TreeNode:\n",
    "#     def __init__(self, x):\n",
    "#         self.val = x\n",
    "#         self.left = None\n",
    "#         self.right = None\n",
    "\n",
    "class Solution:\n",
    "    def maxProduct(self, root: TreeNode) -> int:\n",
    "\n",
    "        def set_node_sum(root):\n",
    "            if not root:\n",
    "                return 0\n",
    "            left_val = set_node_sum(root.left)            \n",
    "            righ_val = set_node_sum(root.right)\n",
    "            root.sum_val = root.val + left_val +righ_val\n",
    "            return root.sum_val\n",
    "\n",
    "        def dfs(root,parent_sum):\n",
    "            if not root:\n",
    "                return -1\n",
    "            product = -1\n",
    "            left_sum_val,right_sum_val = 0,0\n",
    "            if root.left:\n",
    "                product = (parent_sum+root.sum_val-root.left.sum_val)*root.left.sum_val \n",
    "                left_sum_val = root.left.sum_val\n",
    "            if root.right:\n",
    "                product = max(product,(parent_sum+root.sum_val-root.right.sum_val)*root.right.sum_val )\n",
    "                right_sum_val = root.right.sum_val\n",
    "\n",
    "            if root.left:\n",
    "                product = max(product,dfs(root.left,parent_sum+root.val+right_sum_val))\n",
    "            if root.right:\n",
    "                product = max(product,dfs(root.right,parent_sum+root.val+left_sum_val))\n",
    "\n",
    "           \n",
    "            return product\n",
    "            \n",
    "        MOD = 10**9 + 7 \n",
    "\n",
    "        set_node_sum(root)\n",
    "\n",
    "        return dfs(root,0)%MOD\n",
    "            \n",
    "            \n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "# Definition for a binary tree node.\n",
    "# class TreeNode:\n",
    "#     def __init__(self, x):\n",
    "#         self.val = x\n",
    "#         self.left = None\n",
    "#         self.right = None\n",
    "\n",
    "class Solution:\n",
    "    def maxProduct(self, root: TreeNode) -> int:\n",
    "        self.tabel = {}\n",
    "        self.res = -1\n",
    "\n",
    "        def get_node_sum(node):\n",
    "            if not node:\n",
    "                return 0\n",
    "            \n",
    "            node_sum = get_node_sum(node.left) + get_node_sum(node.right) + node.val\n",
    "            self.tabel[node] = node_sum\n",
    "            return node_sum\n",
    "        \n",
    "        def travel(node):\n",
    "            if not node:\n",
    "                return \n",
    "            \n",
    "            # 假设该节点是被截断的\n",
    "            if node != root:\n",
    "                tmp_res = self.tabel[node]*(self.tabel[root]-self.tabel[node])\n",
    "                self.res = max(self.res, tmp_res)\n",
    "            \n",
    "            travel(node.left)\n",
    "            travel(node.right)\n",
    "        \n",
    "        get_node_sum(root)\n",
    "        travel(root)\n",
    "\n",
    "        return int(self.res % (1e9+7))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "# Definition for a binary tree node.\n",
    "# class TreeNode:\n",
    "#     def __init__(self, val=0, left=None, right=None):\n",
    "#         self.val = val\n",
    "#         self.left = left\n",
    "#         self.right = right\n",
    "class Solution:\n",
    "    def maxProduct(self, root: TreeNode) -> int:\n",
    "        sum_dic = {}\n",
    "        def sum_of_tree(root):\n",
    "            sum_of_cur = 0\n",
    "            if not root:\n",
    "                return sum_of_cur\n",
    "            sum_of_cur += root.val\n",
    "            sum_of_left = sum_of_tree(root.left)\n",
    "            sum_of_right = sum_of_tree(root.right)\n",
    "            sum_dic[root] = sum_of_cur + sum_of_left + sum_of_right\n",
    "            sum_of_cur = sum_of_cur + sum_of_left + sum_of_right\n",
    "            return sum_of_cur\n",
    "        sum_of_root = sum_of_tree(root)\n",
    "        max_product = -float('inf')\n",
    "        for i in sum_dic.values():\n",
    "            cur_product = i * (sum_of_root - i)\n",
    "            max_product = max(cur_product, max_product)\n",
    "        return max_product % (10**9 + 7)\n",
    "\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "# Definition for a binary tree node.\n",
    "# class TreeNode:\n",
    "#     def __init__(self, val=0, left=None, right=None):\n",
    "#         self.val = val\n",
    "#         self.left = left\n",
    "#         self.right = right\n",
    "class Solution:\n",
    "    def maxProduct(self, root):\n",
    "        \"\"\"\n",
    "        :type root: TreeNode\n",
    "        :rtype: int\n",
    "        \"\"\"\n",
    "        dic = {}\n",
    "        \n",
    "        def SumOfTree(node):\n",
    "            if not node:\n",
    "                return 0\n",
    "            ls, rs = SumOfTree(node.left), SumOfTree(node.right)\n",
    "            \n",
    "            dic[node] = ls + rs + node.val\n",
    "            return dic[node]\n",
    "        \n",
    "        SumOfTree(root)\n",
    "        TotalSum = dic[root]\n",
    " \n",
    "        self.res = 0\n",
    "        def dfs(node):\n",
    "            if not node:\n",
    "                return\n",
    "            \n",
    "            tmp = (TotalSum - dic[node]) * dic[node]\n",
    "            self.res = max(self.res, tmp)\n",
    "            \n",
    "            dfs(node.left)\n",
    "            dfs(node.right)\n",
    "        dfs(root)\n",
    "        return self.res % (10 ** 9 + 7)\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "# Definition for a binary tree node.\n",
    "# class TreeNode:\n",
    "#     def __init__(self, x):\n",
    "#         self.val = x\n",
    "#         self.left = None\n",
    "#         self.right = None\n",
    "\n",
    "class Solution:\n",
    "    def maxProduct(self, root: TreeNode) -> int:\n",
    "        tree_sum = {None:0}\n",
    "        def find_sum(node):\n",
    "            if not node:\n",
    "                return 0\n",
    "            tree_sum[node] = node.val + find_sum(node.left) + find_sum(node.right)\n",
    "            return tree_sum[node]\n",
    "        find_sum(root)\n",
    "        self.ans = 0\n",
    "        def findAnswer(node, remind):\n",
    "            if not node:\n",
    "                return\n",
    "            if tree_sum[node.left] > tree_sum[node.right]:\n",
    "                self.ans = max(self.ans, tree_sum[node.left] * (tree_sum[node.right] + node.val + remind))\n",
    "            else:\n",
    "                self.ans = max(self.ans, tree_sum[node.right] * (tree_sum[node.left] + node.val + remind))\n",
    "            findAnswer(node.left, remind + tree_sum[node.right] + node.val) \n",
    "            findAnswer(node.right, remind + tree_sum[node.left] + node.val) \n",
    "        findAnswer(root, 0)\n",
    "        return self.ans % (10 ** 9 + 7)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "# Definition for a binary tree node.\n",
    "# class TreeNode:\n",
    "#     def __init__(self, x):\n",
    "#         self.val = x\n",
    "#         self.left = None\n",
    "#         self.right = None\n",
    "\n",
    "class Solution:\n",
    "    def maxProduct(self, root: TreeNode) -> int:\n",
    "        def remark_sum(root: TreeNode):\n",
    "            if root is None:\n",
    "                return 0\n",
    "            else:\n",
    "                root.sum = remark_sum(root.left) + remark_sum(root.right) + root.val\n",
    "                return root.sum\n",
    "        total_sum = remark_sum(root)\n",
    "\n",
    "        def max_product(root: TreeNode) -> int:\n",
    "            if root is None:\n",
    "                return 0\n",
    "            else:\n",
    "                sum_choices = []\n",
    "                if root.left is not None:\n",
    "                    sum_choices.append(root.left.sum * (total_sum - root.left.sum))\n",
    "                if root.right is not None:\n",
    "                    sum_choices.append(root.right.sum * (total_sum - root.right.sum))\n",
    "                sum_choices.append(max_product(root.left))\n",
    "                sum_choices.append(max_product(root.right))\n",
    "                return max(sum_choices)\n",
    "\n",
    "        return max_product(root) % (10**9 + 7)\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "# Definition for a binary tree node.\n",
    "# class TreeNode:\n",
    "#     def __init__(self, x):\n",
    "#         self.val = x\n",
    "#         self.left = None\n",
    "#         self.right = None\n",
    "\n",
    "class Solution:\n",
    "    def maxProduct(self, root: TreeNode) -> int:\n",
    "        di={}\n",
    "        i=0\n",
    "        def helper(root):\n",
    "            nonlocal i\n",
    "            if root is None:\n",
    "                return 0\n",
    "            j=i\n",
    "            i=i+1\n",
    "            left=helper(root.left)\n",
    "            right=helper(root.right)\n",
    "            val=left+right+root.val\n",
    "            di[j]=val\n",
    "            return val\n",
    "        \n",
    "        helper(root)\n",
    "        #print(di)\n",
    "\n",
    "        i=0\n",
    "        res=float(\"-inf\")\n",
    "        def helper2(root):\n",
    "            nonlocal i\n",
    "            nonlocal res\n",
    "            if root is None:\n",
    "                return None\n",
    "            j=i\n",
    "            i=i+1\n",
    "            res=max(res,(di[0]-di[j])*di[j])\n",
    "            #print(j,res)\n",
    "            helper2(root.left)\n",
    "            helper2(root.right)\n",
    "        \n",
    "        helper2(root)  \n",
    "        return res%(10**9+7)\n",
    "\n",
    "\n",
    "        # print(di)\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "# Definition for a binary tree node.\n",
    "# class TreeNode:\n",
    "#     def __init__(self, x):\n",
    "#         self.val = x\n",
    "#         self.left = None\n",
    "#         self.right = None\n",
    "\n",
    "class Solution:\n",
    "    def maxProduct(self, root: TreeNode) -> int:\n",
    "        tree_sum = {None:0}\n",
    "        def find_sum(node):\n",
    "            if not node:\n",
    "                return 0\n",
    "            tree_sum[node] = node.val + find_sum(node.left) + find_sum(node.right)\n",
    "            return tree_sum[node]\n",
    "        find_sum(root)\n",
    "        self.ans = 0\n",
    "        def findAnswer(node, remind):\n",
    "            if not node:\n",
    "                return\n",
    "            temp = tree_sum[node.left] * (tree_sum[node.right] + node.val + remind)\n",
    "            if temp > self.ans:\n",
    "                self.ans = temp\n",
    "            temp = tree_sum[node.right] * (tree_sum[node.left] + node.val + remind)\n",
    "            if temp > self.ans:\n",
    "                self.ans = temp\n",
    "            findAnswer(node.left, remind + tree_sum[node.right] + node.val) \n",
    "            findAnswer(node.right, remind + tree_sum[node.left] + node.val) \n",
    "        findAnswer(root, 0)\n",
    "        return self.ans % (10 ** 9 + 7)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maxProduct(self, root: TreeNode) -> int:\n",
    "        self.sum = 0\n",
    "        self.cur_t = 0\n",
    "        def get_sum(r):\n",
    "            if r:\n",
    "                self.sum += r.val\n",
    "                if not r.left and not r.right:\n",
    "                    self.cur_t = r.val\n",
    "                else:\n",
    "                    get_sum(r.left)\n",
    "                    get_sum(r.right)\n",
    "        get_sum(root)\n",
    "        self.target = self.sum/2\n",
    "        self.cur_x = abs(self.target-self.cur_t)\n",
    "        def find_tar(r):\n",
    "            if r:\n",
    "                s = r.val\n",
    "                s += find_tar(r.left)\n",
    "                s += find_tar(r.right)\n",
    "                cur_x = abs(s - self.target)\n",
    "                if  cur_x < self.cur_x:\n",
    "                    self.cur_t = s\n",
    "                    self.cur_x = cur_x\n",
    "                return s\n",
    "            else:\n",
    "                return 0\n",
    "        find_tar(root)\n",
    "        return ((self.sum - self.cur_t) * self.cur_t) % 1000000007"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "# Definition for a binary tree node.\n",
    "# class TreeNode:\n",
    "#     def __init__(self, x):\n",
    "#         self.val = x\n",
    "#         self.left = None\n",
    "#         self.right = None\n",
    "\n",
    "class Solution:\n",
    "    def maxProduct(self, root: TreeNode) -> int:\n",
    "        node_left_right_value = dict()\n",
    "\n",
    "        def dfs(node: TreeNode):\n",
    "            if node is None:\n",
    "                return 0\n",
    "            l = dfs(node.left)\n",
    "            r = dfs(node.right)\n",
    "            node_left_right_value[node] = [l, r]\n",
    "            return l + r + node.val\n",
    "\n",
    "        mod = 10 ** 9 + 7\n",
    "        res = 0\n",
    "\n",
    "        def deal(node: TreeNode):\n",
    "            nonlocal res\n",
    "            if node is None:\n",
    "                return\n",
    "            l, r = node_left_right_value[node]\n",
    "            temp = max(l * (total - l), r * (total - r))\n",
    "            if temp > res:\n",
    "                res = temp\n",
    "\n",
    "            deal(node.left)\n",
    "            deal(node.right)\n",
    "\n",
    "        total = dfs(root)\n",
    "        deal(root)\n",
    "        return res % mod\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "# Definition for a binary tree node.\n",
    "# class TreeNode:\n",
    "#     def __init__(self, x):\n",
    "#         self.val = x\n",
    "#         self.left = None\n",
    "#         self.right = None\n",
    "class Solution:\n",
    "    def maxProduct(self, root: TreeNode) -> int:\n",
    "        add_dict = []\n",
    "        MOD = 1000000007\n",
    "        def caculate_add(node):\n",
    "            #计算某一节点下所有子节点的和\n",
    "            add = 0\n",
    "            if node == None:\n",
    "                return add\n",
    "            add += node.val + caculate_add(node.left) + caculate_add(node.right)\n",
    "            add_dict.append(add)\n",
    "            return add\n",
    "        res = 0            \n",
    "        sum_all = caculate_add(root)\n",
    "        for i in add_dict:\n",
    "            result =i * (sum_all - i)\n",
    "            if result > res:\n",
    "                res = result\n",
    "        res %= MOD\n",
    "        return res\n",
    "            \n",
    "\n",
    "\n",
    "\n",
    "\n",
    "\n",
    "        \n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "# Definition for a binary tree node.\n",
    "# class TreeNode:\n",
    "#     def __init__(self, x):\n",
    "#         self.val = x\n",
    "#         self.left = None\n",
    "#         self.right = None\n",
    "\n",
    "class Solution:\n",
    "    def maxProduct(self, root: TreeNode) -> int:\n",
    "        total, mod, res = 0, 10**9 + 7, 0\n",
    "        def dfs(root):\n",
    "            nonlocal res\n",
    "            if not root:\n",
    "                return 0\n",
    "            l = dfs(root.left)\n",
    "            r = dfs(root.right)\n",
    "            res = max(res,l*(total-l),r*(total-r))\n",
    "            return l+r+root.val\n",
    "        total = dfs(root)\n",
    "        dfs(root)\n",
    "        return res%mod"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "# Definition for a binary tree node.\n",
    "# class TreeNode:\n",
    "#     def __init__(self, x):\n",
    "#         self.val = x\n",
    "#         self.left = None\n",
    "#         self.right = None\n",
    "\n",
    "class Solution:\n",
    "    def maxProduct(self, root: TreeNode) -> int:\n",
    "        #方法：先求总和h，之后以某节点切断，求下面的值之和a，算一下（h-a）*a与res比较留下大的\n",
    "        def main1(root):#add为本节点的外侧全部和，返回以该节点为根的子树和\n",
    "            if not root:return 0\n",
    "            l,r = main1(root.left),main1(root.right)\n",
    "            return root.val+l+r\n",
    "        h=main1(root)\n",
    "        self.res=0\n",
    "        def main(root):#add为本节点的外侧全部和，返回以该节点为根的子树和\n",
    "            if not root:return 0\n",
    "            l,r = main(root.left),main(root.right)\n",
    "            self.res=max(self.res,(h-l)*l,(h-r)*r)\n",
    "            return root.val+l+r\n",
    "        main(root)\n",
    "        return self.res%(10**9+7)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "# Definition for a binary tree node.\n",
    "# class TreeNode:\n",
    "#     def __init__(self, val=0, left=None, right=None):\n",
    "#         self.val = val\n",
    "#         self.left = left\n",
    "#         self.right = right\n",
    "class Solution:\n",
    "    def maxProduct(self, root: Optional[TreeNode]) -> int:\n",
    "        tree_info = []\n",
    "        def iter_process(node):\n",
    "            if node is None:\n",
    "                return 0,0\n",
    "            idx = len(tree_info)\n",
    "            tree_info.append([0,0,0,0])\n",
    "            lsum,lnum = iter_process(node.left)\n",
    "            rsum,rnum = iter_process(node.right)\n",
    "            tree_info[idx] = [lsum,rsum,lnum,rnum]\n",
    "            return lsum+rsum+node.val,lnum+rnum+1\n",
    "\n",
    "        all_sum = iter_process(root)[0]\n",
    "        max_product = 0\n",
    "        def find_max_product(node,idx):\n",
    "            if node is None:\n",
    "                return\n",
    "            nonlocal max_product\n",
    "            lsum, rsum, lnum, rnum = tree_info[idx]\n",
    "            lpro = lsum * (all_sum-lsum)\n",
    "            rpro = rsum * (all_sum-rsum)\n",
    "            max_product = max(max_product, lpro, rpro)\n",
    "            find_max_product(node.left,idx+1)\n",
    "            find_max_product(node.right,idx+lnum+1)\n",
    "        find_max_product(root,0)\n",
    "        return max_product%(10**9+7)\n",
    "            \n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "# Definition for a binary tree node.\n",
    "# class TreeNode:\n",
    "#     def __init__(self, x):\n",
    "#         self.val = x\n",
    "#         self.left = None\n",
    "#         self.right = None\n",
    "\n",
    "class Solution:\n",
    "    def maxProduct(self, root: TreeNode) -> int:\n",
    "        res = []\n",
    "        def dfs(root):\n",
    "            if not root:\n",
    "                return 0\n",
    "            s = root.val\n",
    "            left = right = 0\n",
    "            if root.left:\n",
    "                left = dfs(root.left)\n",
    "            if root.right:\n",
    "                right =dfs(root.right)\n",
    "            s += left+right\n",
    "            res.append(s)\n",
    "            return s\n",
    "        s = dfs(root)\n",
    "        res.remove(s)\n",
    "        mx = 0\n",
    "        for n in res:\n",
    "            mx = max(mx, n*(s-n))\n",
    "        return mx%(10**9+7)\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "# Definition for a binary tree node.\n",
    "# class TreeNode:\n",
    "#     def __init__(self, val=0, left=None, right=None):\n",
    "#         self.val = val\n",
    "#         self.left = left\n",
    "#         self.right = right\n",
    "from functools import lru_cache\n",
    "class Solution:\n",
    "    \n",
    "    def maxProduct(self, root: Optional[TreeNode]) -> int:\n",
    "        result = 0\n",
    "        def dfs(root):\n",
    "            if not root:\n",
    "                return 0\n",
    "            return (root.val + dfs(root.left) + dfs(root.right))\n",
    "        all_sum = dfs(root)\n",
    "\n",
    "        @lru_cache(None)\n",
    "        def get_sub_tree_sum(root):\n",
    "            nonlocal result\n",
    "            nonlocal all_sum\n",
    "            if not root:\n",
    "                return 0\n",
    "            \n",
    "            left_sum = get_sub_tree_sum(root.left)\n",
    "            right_sum = get_sub_tree_sum(root.right)\n",
    "\n",
    "            temp = root.val + left_sum + right_sum\n",
    "\n",
    "            result = max([result,(all_sum-temp)*temp])\n",
    "            \n",
    "            return temp\n",
    "        get_sub_tree_sum(root)\n",
    "\n",
    "        return result%(10**9+7)\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "#!/usr/bin/env python\n",
    "# -*- coding: utf-8 -*-\n",
    "# @Time    : 2022/10/19 19:23\n",
    "# @Author  : David\n",
    "# @File    : 1339. 分裂二叉树的最大乘积.py\n",
    "# @Description : 1339. 分裂二叉树的最大乘积\n",
    "from functools import cache\n",
    "from typing import Optional\n",
    "\n",
    "\"\"\"\n",
    "    给你一棵二叉树，它的根为 root 。请你删除 1 条边，使二叉树分裂成两棵子树，且它们子树和的乘积尽可能大。\n",
    "    由于答案可能会很大，请你将结果对 10^9 + 7 取模后再返回。\n",
    "    \n",
    "    提示：\n",
    "        每棵树最多有 50000 个节点，且至少有 2 个节点。\n",
    "        每个节点的值在 [1, 10000] 之间。\n",
    "\n",
    "来源：力扣（LeetCode）\n",
    "链接：https://leetcode.cn/problems/maximum-product-of-splitted-binary-tree\n",
    "著作权归领扣网络所有。商业转载请联系官方授权，非商业转载请注明出处。\n",
    "\"\"\"\n",
    "\n",
    "\n",
    "# class TreeNode:\n",
    "#     def __init__(self, val=0, left=None, right=None):\n",
    "#         self.val = val\n",
    "#         self.left = left\n",
    "#         self.right = right\n",
    "\n",
    "\n",
    "class Solution:\n",
    "    def maxProduct(self, root: Optional[TreeNode]) -> int:\n",
    "        \"\"\"\n",
    "            乘积 = 某个节点下所有子节点的和 *（整个树的和 - 某个节点下所有子节点的和）\n",
    "            :param root: 根节点\n",
    "            :return: 两棵子树乘积的最大值\n",
    "        \"\"\"\n",
    "\n",
    "        @cache\n",
    "        def dfs(node: Optional[TreeNode]) -> int:\n",
    "            \"\"\"\n",
    "                深度优先遍历, 计算当前节点及自己点的和\n",
    "                使用的是后序遍历: 左 -> 右 -> 根\n",
    "                :param node: 当前节点\n",
    "                :return: 当前节点及子节点的和\n",
    "            \"\"\"\n",
    "            if node is None:\n",
    "                return 0\n",
    "            else:\n",
    "                # 当前节点的和等于左子树的和 + 右子树的和 + 当前节点值\n",
    "                sum_list.append(dfs(node.left) + dfs(node.right) + node.val)\n",
    "                return sum_list[-1]\n",
    "\n",
    "        sum_list = list()  # 所有节点的和值\n",
    "        root_sum = dfs(root)  # 计算根节点的和值(整棵树的和)\n",
    "        answer = 0\n",
    "        # 乘积 = 某个节点下所有子节点的和 *（整个树的和 - 某个节点下所有子节点的和）\n",
    "        for x in sum_list:\n",
    "            answer = max(answer, x * (root_sum - x)) \n",
    "        \n",
    "        return answer% (10 ** 9 + 7)\n",
    "\n",
    "    def Main(self):\n",
    "        root = TreeNode(1, TreeNode(2, TreeNode(4), TreeNode(5)), TreeNode(3, TreeNode(6)))\n",
    "        print(self.maxProduct(root=root))\n",
    "\n",
    "\n",
    "if __name__ == '__main__':\n",
    "    Solution().Main()\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "# Definition for a binary tree node.\n",
    "# class TreeNode:\n",
    "#     def __init__(self, val=0, left=None, right=None):\n",
    "#         self.val = val\n",
    "#         self.left = left\n",
    "#         self.right = right\n",
    "class Solution:\n",
    "    def maxProduct(self, root: Optional[TreeNode]) -> int:\n",
    "        @cache\n",
    "        def S(u):\n",
    "            if u is None:\n",
    "                return 0\n",
    "            return S(u.left) + S(u.right) + u.val\n",
    "        total = S(root)\n",
    "        ans = 0\n",
    "        def dfs(u):\n",
    "            if u is None:\n",
    "                return\n",
    "            nonlocal ans\n",
    "            ans = max(ans, S(u) * (total - S(u)))\n",
    "            dfs(u.left)\n",
    "            dfs(u.right)\n",
    "        dfs(root)\n",
    "        return ans % (10**9+7)\n",
    "\n",
    "        "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "# Definition for a binary tree node.\n",
    "# class TreeNode:\n",
    "#     def __init__(self, val=0, left=None, right=None):\n",
    "#         self.val = val\n",
    "#         self.left = left\n",
    "#         self.right = right\n",
    "class Solution:\n",
    "    def maxProduct(self, root: Optional[TreeNode]) -> int:\n",
    "        @cache\n",
    "        def get_sum(root):\n",
    "            if not root:\n",
    "                return 0\n",
    "            return root.val + get_sum(root.left) + get_sum(root.right)\n",
    "        \n",
    "        total = get_sum(root)\n",
    "        def dfs(root):\n",
    "            if not root:\n",
    "                return 0\n",
    "            \n",
    "            self.res = max(self.res, get_sum(root) * (total - get_sum(root)))\n",
    "            dfs(root.left)\n",
    "            dfs(root.right)\n",
    "        \n",
    "        self.res = -inf\n",
    "        dfs(root)\n",
    "        return self.res % (10 ** 9 + 7)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "# Definition for a binary tree node.\n",
    "# class TreeNode:\n",
    "#     def __init__(self, val=0, left=None, right=None):\n",
    "#         self.val = val\n",
    "#         self.left = left\n",
    "#         self.right = right\n",
    "class Solution:\n",
    "    def maxProduct(self, root: Optional[TreeNode]) -> int:\n",
    "        \n",
    "        @lru_cache(None)\n",
    "        def total(node):\n",
    "            if not node:\n",
    "                return 0\n",
    "            t_sum = node.val\n",
    "            t_sum += total(node.left)\n",
    "            t_sum += total(node.right)\n",
    "            return t_sum\n",
    "\n",
    "        t_sum = total(root)\n",
    "\n",
    "        # @lru_cache(None)\n",
    "        def dfs(node):\n",
    "            nonlocal t_sum\n",
    "            res = 0\n",
    "            if node:\n",
    "                res = max(res, dfs(node.left))\n",
    "                l = total(node.left)\n",
    "                res = max(res, l*(t_sum-l))\n",
    "                res = max(res, dfs(node.right))\n",
    "                r = total(node.right)\n",
    "                res = max(res, r*(t_sum-r))\n",
    "            return res\n",
    "        return dfs(root) % (10**9 + 7)\n",
    "            \n",
    "            \n",
    "            "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "from collections import deque\n",
    "from functools import cache\n",
    "from math import inf\n",
    "\n",
    "class Solution:\n",
    "    def maxProduct(self, root: Optional[TreeNode]) -> int:\n",
    "        @cache\n",
    "        def sumOf(root: Optional[TreeNode]) -> int:\n",
    "            if root is None:\n",
    "                return 0\n",
    "            return sumOf(root.left) + sumOf(root.right) + root.val\n",
    "\n",
    "        total, q = 0, deque()\n",
    "        q.append(root)\n",
    "        while q:\n",
    "            node: TreeNode = q.popleft()\n",
    "            total += node.val\n",
    "            if node.left is not None:\n",
    "                q.append(node.left)\n",
    "            if node.right is not None:\n",
    "                q.append(node.right)\n",
    "\n",
    "        m = -inf\n",
    "        q.clear()\n",
    "        q.append(root)\n",
    "        while q:\n",
    "            node: TreeNode = q.popleft()\n",
    "            s = sumOf(node)\n",
    "            m = max(m, s * (total - s))\n",
    "            if node.left is not None:\n",
    "                q.append(node.left)\n",
    "            if node.right is not None:\n",
    "                q.append(node.right)\n",
    "        return m % (10**9 + 7)\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "# Definition for a binary tree node.\n",
    "# class TreeNode:\n",
    "#     def __init__(self, x):\n",
    "#         self.val = x\n",
    "#         self.left = None\n",
    "#         self.right = None\n",
    "\n",
    "class Solution:\n",
    "    def maxProduct(self, root: TreeNode) -> int:\n",
    "        nodesumdict = dict()\n",
    "        \n",
    "        def treeSum(node):\n",
    "            nonlocal nodesumdict\n",
    "            if not node:\n",
    "                return 0\n",
    "\n",
    "            left = treeSum(node.left)\n",
    "            right = treeSum(node.right)\n",
    "            \n",
    "            nodesumdict[node] = {\"left\":left, \"right\":right}\n",
    "            \n",
    "            return node.val + left + right\n",
    "        \n",
    "        treeSum(root)\n",
    "       \n",
    "        res = float('-inf')\n",
    "        \n",
    "        \n",
    "        def maxprod(node, presum, leftsum, rightsum):\n",
    "            # print(node.val if node else None, leftsum, rightsum)\n",
    "            nonlocal res\n",
    "            \n",
    "            if leftsum == rightsum == 0:\n",
    "                return\n",
    "            \n",
    "            presum += node.val\n",
    "            \n",
    "            \n",
    "            if leftsum > 0 and rightsum > 0:\n",
    "                res = max(res, (leftsum+presum)*rightsum, (rightsum+presum)*leftsum)\n",
    "                maxprod(node.left, presum+rightsum, nodesumdict[node.left]['left'], nodesumdict[node.left]['right'])\n",
    "                maxprod(node.right, presum+leftsum, nodesumdict[node.right]['left'], nodesumdict[node.right]['right'])\n",
    "            elif leftsum == 0:\n",
    "                res = max(res, (leftsum+presum)*rightsum)\n",
    "                maxprod(node.right, presum, nodesumdict[node.right]['left'], nodesumdict[node.right]['right'])\n",
    "            elif rightsum == 0:\n",
    "                res = max(res, (rightsum+presum)*leftsum)\n",
    "                maxprod(node.left, presum, nodesumdict[node.left]['left'], nodesumdict[node.left]['right'])\n",
    "\n",
    "        maxprod(root, 0, nodesumdict[root]['left'], nodesumdict[root]['right'])\n",
    "        return res%(10**9 + 7)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "# Definition for a binary tree node.\n",
    "# class TreeNode:\n",
    "#     def __init__(self, val=0, left=None, right=None):\n",
    "#         self.val = val\n",
    "#         self.left = left\n",
    "#         self.right = right\n",
    "class Solution:\n",
    "    def __init__(self):\n",
    "        self.ans = 0\n",
    "    def maxProduct(self, root: Optional[TreeNode]) -> int:\n",
    "        @lru_cache(None)\n",
    "        def getsum(node):\n",
    "            if not node:\n",
    "                return 0\n",
    "            return getsum(node.left) + getsum(node.right) + node.val\n",
    "        allsum = getsum(root)\n",
    "        def dfs(node):\n",
    "            if not node:\n",
    "                return\n",
    "            left = getsum(node.left)\n",
    "            right = getsum(node.right)\n",
    "            \n",
    "            tmp1 = min(left, allsum - left)\n",
    "            tmp2 = min(right, allsum - right)\n",
    "            self.ans = max(self.ans, tmp1, tmp2)\n",
    "            \n",
    "            if left > (allsum >> 1):\n",
    "                dfs(node.left)\n",
    "            else:\n",
    "                dfs(node.right)\n",
    "        \n",
    "        dfs(root)\n",
    "        return (self.ans * (allsum - self.ans)) % (10**9 + 7)\n",
    "\n",
    "        \n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "# Definition for a binary tree node.\n",
    "# class TreeNode:\n",
    "#     def __init__(self, val=0, left=None, right=None):\n",
    "#         self.val = val\n",
    "#         self.left = left\n",
    "#         self.right = right\n",
    "class Solution:\n",
    "    def maxProduct(self, root: Optional[TreeNode]) -> int:\n",
    "        best = 0\n",
    "        table = {}\n",
    "\n",
    "        @lru_cache(None)\n",
    "        def go(node):\n",
    "            if not node:\n",
    "                return 0\n",
    "            left = go(node.left)\n",
    "            right = go(node.right)\n",
    "            table[node] = left + node.val + right\n",
    "            return table[node]\n",
    "        \n",
    "        go(root)\n",
    "        best = 0\n",
    "        for key, value in table.items():\n",
    "            best = max(best, (table[root] - value) * value)\n",
    "        return best % int(1e9 + 7)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "# Definition for a binary tree node.\n",
    "# class TreeNode:\n",
    "#     def __init__(self, val=0, left=None, right=None):\n",
    "#         self.val = val\n",
    "#         self.left = left\n",
    "#         self.right = right\n",
    "class Solution:\n",
    "    def maxProduct(self, root: Optional[TreeNode]) -> int:\n",
    "        \n",
    "        @lru_cache(None)\n",
    "        def total(node):\n",
    "            if not node:\n",
    "                return 0\n",
    "            t_sum = node.val\n",
    "            t_sum += total(node.left)\n",
    "            t_sum += total(node.right)\n",
    "            return t_sum\n",
    "\n",
    "        t_sum = total(root)\n",
    "\n",
    "        # @lru_cache(None)\n",
    "        def dfs(node):\n",
    "            nonlocal t_sum\n",
    "            res = 0\n",
    "            if node:\n",
    "                l = dfs(node.left)\n",
    "                r = dfs(node.right)\n",
    "\n",
    "                sub = node.val + total(node.left) + total(node.right)\n",
    "                res = max(l, r, sub*(t_sum-sub))\n",
    "            return res\n",
    "\n",
    "        return dfs(root) % (10**9 + 7)\n",
    "            \n",
    "            \n",
    "            "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "# Definition for a binary tree node.\n",
    "# class TreeNode:\n",
    "#     def __init__(self, x):\n",
    "#         self.val = x\n",
    "#         self.left = None\n",
    "#         self.right = None\n",
    "from functools import lru_cache \n",
    "\n",
    "class Solution:\n",
    "    def maxProduct(self, root: TreeNode) -> int:\n",
    "        \n",
    "        max_prod = 0\n",
    "\n",
    "        @lru_cache(None)\n",
    "        def dp(root):\n",
    "            if not root.left and not root.right:\n",
    "                return root.val\n",
    "            cur_sum = root.val\n",
    "            if root.left:\n",
    "                cur_sum += dp(root.left)\n",
    "            if root.right:\n",
    "                cur_sum += dp(root.right)\n",
    "            return cur_sum\n",
    "\n",
    "        total_sum = dp(root)\n",
    "\n",
    "        def dfs(root):\n",
    "            nonlocal max_prod, total_sum\n",
    "            if root.left:\n",
    "                max_prod = max(max_prod, (total_sum - dp(root.left)) * dp(root.left))\n",
    "                dfs(root.left)\n",
    "            if root.right:\n",
    "                max_prod = max(max_prod, (total_sum - dp(root.right)) * dp(root.right))\n",
    "                dfs(root.right)\n",
    "\n",
    "        \n",
    "        dfs(root)\n",
    "        return max_prod % (10 ** 9 + 7)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "# Definition for a binary tree node.\n",
    "# class TreeNode:\n",
    "#     def __init__(self, x):\n",
    "#         self.val = x\n",
    "#         self.left = None\n",
    "#         self.right = None\n",
    "\n",
    "class Solution:\n",
    "    def maxProduct(self, root: TreeNode) -> int:\n",
    "        max_ = 0\n",
    "        @lru_cache(None)\n",
    "        def sum_(root):\n",
    "            if not root:\n",
    "                return 0\n",
    "            l = sum_(root.left)\n",
    "            r = sum_(root.right)\n",
    "            return l + r + root.val\n",
    "        t = sum_(root)\n",
    "        mod = 10 ** 9 + 7\n",
    "        def recur(root):\n",
    "            nonlocal max_,t,mod\n",
    "            if not root:\n",
    "                return 0\n",
    "            l = recur(root.left)\n",
    "            r = recur(root.right)\n",
    "            if root.left:\n",
    "                max_ = max(max_,((t - l) * l))\n",
    "            if root.right:\n",
    "                max_ = max(max_,((t - r) * r))\n",
    "            return l + r + root.val\n",
    "        recur(root)\n",
    "        return max_ % mod\n",
    "            "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "# Definition for a binary tree node.\n",
    "# class TreeNode:\n",
    "#     def __init__(self, val=0, left=None, right=None):\n",
    "#         self.val = val\n",
    "#         self.left = left\n",
    "#         self.right = right\n",
    "class Solution:\n",
    "    def maxProduct(self, root: Optional[TreeNode]) -> int:\n",
    "\n",
    "        self.ret = 0\n",
    "        \n",
    "        @lru_cache(None)\n",
    "        def getall(r):\n",
    "            if not r:\n",
    "                return 0\n",
    "            return r.val + getall(r.left) + getall(r.right)\n",
    "        \n",
    "        a = getall(root)\n",
    "        self.dif = inf\n",
    "        def chk(r):\n",
    "            if not r:\n",
    "                return\n",
    "            v = getall(r)\n",
    "            # print(r, v)\n",
    "            if v < a and abs(a - v - v) < self.dif:\n",
    "                self.dif = min(self.dif, abs(a - v - v))\n",
    "                self.ret = v * (a - v) % (10 ** 9 + 7)\n",
    "            chk(r.left)\n",
    "            chk(r.right)\n",
    "        # print(a, self.dif)\n",
    "        chk(root)\n",
    "        return self.ret        \n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maxProduct(self, s: str) -> int:\n",
    "        a, b = [], []\n",
    "        ans = 0\n",
    "        n = len(s)\n",
    "\n",
    "        def isPalindromic(a):\n",
    "            n = len(a)\n",
    "            for i in range(n // 2):\n",
    "                if a[i] != a[n-1 - i]:\n",
    "                    return False\n",
    "            return True\n",
    "\n",
    "        # 表示考虑前i字符时候的结果\n",
    "        def dfs(i):\n",
    "            nonlocal a, b, ans\n",
    "\n",
    "            if i == n:\n",
    "                if len(a) * len(b) > ans and isPalindromic(a) and isPalindromic(b):\n",
    "                    ans = len(a) * len(b)\n",
    "                return \n",
    "            dfs(i + 1)\n",
    "\n",
    "            a = a + [s[i]]\n",
    "            dfs(i + 1)\n",
    "            a = a[:-1]\n",
    "\n",
    "            b = b + [s[i]]\n",
    "            dfs(i+1)\n",
    "            b = b[:-1]\n",
    "\n",
    "        dfs(0)\n",
    "\n",
    "        return ans"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maxProduct(self, s: str) -> int:\n",
    "        def check(st):\n",
    "            left, right = 0, len(st) - 1\n",
    "            while left < right:\n",
    "                if st[left] != st[right]:\n",
    "                    return False\n",
    "                left += 1\n",
    "                right -= 1\n",
    "            return True\n",
    "\n",
    "        dp, res = [], 1\n",
    "        for i in range(1 << len(s)):\n",
    "            sp = \"\"\n",
    "            for j in range(len(s)):\n",
    "                if i & (1 << j):\n",
    "                    sp += s[j]\n",
    "            dp.append(check(sp))\n",
    "        for i in range(1 << len(s) - 1):\n",
    "            if dp[i]:\n",
    "                for j in range(i + 1, 1 << len(s)):\n",
    "                    if i & j == 0 and dp[j]:\n",
    "                        res = max(res, i.bit_count() * j.bit_count())\n",
    "        return res"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maxProduct(self, s: str) -> int:\n",
    "        ret = 1\n",
    "        n = len(s)\n",
    "        def dfs(i, s1, s2):\n",
    "            nonlocal ret\n",
    "            if i == n:\n",
    "                k = len(s1) * len(s2)\n",
    "                if k > ret and s1 == s1[::-1] and s2 == s2[::-1]:\n",
    "                    ret = k\n",
    "                return \n",
    "            dfs(i + 1, s1, s2)\n",
    "            dfs(i + 1, s1 + s[i], s2)\n",
    "            dfs(i + 1, s1, s2 + s[i])\n",
    "        dfs(0, '', '')\n",
    "        return ret             "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maxProduct(self, s: str) -> int:\n",
    "\n",
    "        def check(x):\n",
    "            pos = []\n",
    "            for i in range(n):\n",
    "                if (x >> i)&1:\n",
    "                    pos.append(i)\n",
    "            i, j = 0, len(pos)-1\n",
    "            while i < j and s[pos[i]] == s[pos[j]]:\n",
    "                i += 1\n",
    "                j -= 1\n",
    "            return i >= j, len(pos)\n",
    "\n",
    "        n = len(s) \n",
    "        dp = [0] * (1 << n) \n",
    "\n",
    "        for i in range(1, 1 << n):\n",
    "            a, b = check(i)\n",
    "            if a:\n",
    "                dp[i] = b\n",
    "        #print(dp)\n",
    "        ans = 0\n",
    "        for i in range(1, 1 << n):\n",
    "            for j in range(i+1, 1 << n):\n",
    "                if dp[i] and dp[j] and i & j == 0:\n",
    "                    ans = max(ans, dp[i] * dp[j])\n",
    "        return ans \n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maxProduct(self, s: str) -> int:\n",
    "        n=len(s)\n",
    "        total=[] #存放所有回文子序列\n",
    "        for i in range(1,1<<n): #用位运算列出所有子序列\n",
    "            temp=''\n",
    "            for j in range(n):\n",
    "                if (1<<j)&i:\n",
    "                    temp+=s[j]\n",
    "            if temp==temp[::-1]: #判断是否为回文\n",
    "                total.append(i)\n",
    "        \n",
    "        def count1(m:int): #统计二进制中1的个数\n",
    "            res=0\n",
    "            while m:\n",
    "                res+=(m&1)\n",
    "                m>>=1\n",
    "            return res\n",
    "        \n",
    "        ret=0\n",
    "        for i in range(len(total)):\n",
    "            for j in range(i+1,len(total)):\n",
    "                if total[i]&total[j]==0:    # total[i]&total[j]为0说明俩子序列不相交\n",
    "                    ret=max(ret,count1(total[i])*count1(total[j])) \n",
    "        return ret                #1的个数表示回文序列的长度，并计算俩长度的乘积"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maxProduct(self, s):\n",
    "        \"\"\"\n",
    "        :type s: str\n",
    "        :rtype: int\n",
    "        \"\"\"\n",
    "\n",
    "        self.res = 0\n",
    "        self.dfs(0, [], [], s)\n",
    "        return self.res\n",
    "\n",
    "    def dfs(self, now, part1, part2, s):\n",
    "        if now == len(s):\n",
    "            self.res = max(self.res, self.dp(part1) * self.dp(part2))\n",
    "            return\n",
    "        \n",
    "        part1.append(s[now])\n",
    "        self.dfs(now + 1, part1, part2, s)\n",
    "        part1.pop()\n",
    "\n",
    "        part2.append(s[now])\n",
    "        self.dfs(now + 1, part1, part2, s)\n",
    "        part2.pop()\n",
    "    \n",
    "    def dp(self, s):\n",
    "        n = len(s)\n",
    "        if n == 0:\n",
    "            return 0\n",
    "        f = [[0] * n for _ in range(n)]\n",
    "        for l in range(1, n + 1):\n",
    "            for left in range(n - l + 1):\n",
    "                right = left + l - 1\n",
    "                if left == right:\n",
    "                    f[left][right] = 1\n",
    "                elif s[left] == s[right]:\n",
    "                    f[left][right] = f[left + 1][right - 1] + 2\n",
    "                else:\n",
    "                    f[left][right] = max(f[left + 1][right], f[left][right - 1])\n",
    "        \n",
    "        return f[0][n - 1]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maxProduct(self, s: str) -> int:\n",
    "        n=len(s)\n",
    "        ans=1\n",
    "\n",
    "        def dfs(s1,s2,pos):\n",
    "            nonlocal ans\n",
    "            if pos==n:\n",
    "                if s1==s1[::-1] and s2==s2[::-1]:\n",
    "                    ans=max(ans,len(s2)*len(s1))\n",
    "                return\n",
    "            dfs(s1,s2,pos+1)\n",
    "            dfs(s1+s[pos],s2,pos+1)\n",
    "            dfs(s1,s2+s[pos],pos+1)\n",
    "\n",
    "\n",
    "        dfs('','',0)\n",
    "        return ans"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maxProduct(self, s: str) -> int:\n",
    "        L = len(s)\n",
    "        def _is_palindromic(mask) -> bool:\n",
    "            buf = []\n",
    "            for i in range(L):\n",
    "                if mask & (1 << i) != 0:\n",
    "                    buf.append(s[i])\n",
    "            return buf == buf[::-1]\n",
    "        index_masks = []\n",
    "        for mask in range(1, 1 << L):\n",
    "            if _is_palindromic(mask):\n",
    "                index_masks.append(mask)\n",
    "        ans = 0\n",
    "        for mi in range(len(index_masks)):\n",
    "            for mj in range(mi + 1, len(index_masks)):\n",
    "                if index_masks[mi] & index_masks[mj] == 0:\n",
    "                    ans = max(ans, bin(index_masks[mi]).count(\"1\") * bin(index_masks[mj]).count(\"1\"))\n",
    "\n",
    "        return ans"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maxProduct(self, s: str) -> int:\n",
    "        def is_palindromic(a):\n",
    "            return a == a[::-1]\n",
    "\n",
    "        ans = 0\n",
    "        a = []\n",
    "        b = []\n",
    "\n",
    "        def dfs(i):\n",
    "            nonlocal ans\n",
    "            if i == len(s):\n",
    "                if len(a) * len(b) > ans and is_palindromic(a) and is_palindromic(b):\n",
    "                    ans = len(a) * len(b)\n",
    "                return\n",
    "\n",
    "            # Do not select the character at position i (skip it).\n",
    "            dfs(i + 1)\n",
    "\n",
    "            # Include the character in a.\n",
    "            a.append(s[i])\n",
    "            dfs(i + 1)\n",
    "            a.pop()\n",
    "\n",
    "            # Include the character in b.\n",
    "            b.append(s[i])\n",
    "            dfs(i + 1)\n",
    "            b.pop()\n",
    "\n",
    "        dfs(0)\n",
    "        return ans"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maxProduct(self, s: str) -> int:\n",
    "        n = len(s)\n",
    "        vis = [False] * n\n",
    "\n",
    "        def check(s: List[str]) -> bool:\n",
    "            # 判断是否是回文串\n",
    "            n = len(s)\n",
    "            left, right = 0, n - 1\n",
    "            while left < right:\n",
    "                if s[left] != s[right]:\n",
    "                    return False\n",
    "                left += 1\n",
    "                right -= 1\n",
    "            return True\n",
    "\n",
    "        def dfs(i: int) -> None:\n",
    "            if i == -1:\n",
    "                s2 = [s[j] for j in range(n) if vis[j]]\n",
    "                if check(s2):\n",
    "                    def dfs_ls(i: int, j: int) -> int:\n",
    "                        if i >= j:\n",
    "                            return int(i == j)\n",
    "                        if s2[i] == s2[j]:\n",
    "                            return dfs_ls(i + 1, j - 1) + 2\n",
    "                        return max(dfs_ls(i + 1, j), dfs_ls(i, j - 1))\n",
    "                    len1 = dfs_ls(0, len(s2) - 1)\n",
    "                    s2 = [s[j] for j in range(n) if not vis[j]]\n",
    "                    len2 = dfs_ls(0, len(s2) - 1)\n",
    "                    nonlocal ans\n",
    "                    ans = max(ans, len1 * len2)\n",
    "                return\n",
    "            vis[i] = True\n",
    "            dfs(i - 1)\n",
    "            vis[i] = False\n",
    "            dfs(i - 1)\n",
    "        ans = 0\n",
    "        dfs(n - 1)\n",
    "        return ans"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maxProduct(self, s: str) -> int:\n",
    "        ans, n = 1, len(s)\n",
    "        mx = 1 << n\n",
    "        dp = [0] * (1 << n)\n",
    "        dp[1] = 1\n",
    "        for mask in range(2, mx):\n",
    "            if mask.bit_count() == 1:\n",
    "                dp[mask] = 1\n",
    "            else:\n",
    "                lb = mask & -mask\n",
    "                low = lb.bit_length() - 1\n",
    "                high = mask.bit_length() - 1\n",
    "                hb = 1 << high\n",
    "                dp[mask] = max(dp[mask ^ lb], dp[mask ^ hb])\n",
    "                if s[low] == s[high]:\n",
    "                    dp[mask] = max(dp[mask], dp[mask ^ lb ^ hb] + 2)\n",
    "        \n",
    "        for mask in range(1, mx):\n",
    "            ans = max(ans, dp[mask] * dp[(mx - 1) ^ mask])\n",
    "\n",
    "        # for mask in range(3, pow(3, n)):\n",
    "        #     seq = [0] * 2\n",
    "        #     for i in range(n):\n",
    "        #         cur = mask % 3\n",
    "        #         if cur:\n",
    "        #             seq[cur - 1] |= 1 << i\n",
    "        #         mask //= 3\n",
    "        #     if not seq[0] or not seq[1]: continue\n",
    "        #     if dp[seq[0]] and dp[seq[1]]: \n",
    "        #         ans = max(ans, seq[0].bit_count() * seq[1].bit_count())\n",
    "        return ans\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\r\n",
    "    def check(self,lf,rt,s):\r\n",
    "        while lf < rt:\r\n",
    "            if s[lf] != s[rt]:\r\n",
    "                return False\r\n",
    "            lf += 1\r\n",
    "            rt -= 1\r\n",
    "        return True\r\n",
    "    def maxProduct(self, s: str) -> int:\r\n",
    "        def dfs(s1,s2,lf,rt):\r\n",
    "            nonlocal res\r\n",
    "            if lf > rt:\r\n",
    "                if self.check(0,len(s1)-1,s1) and self.check(0,len(s2)-1,s2):\r\n",
    "                    res = max(res,len(s1)*len(s2))\r\n",
    "                return\r\n",
    "            dfs(s1+s[lf],s2,lf+1,rt)\r\n",
    "            dfs(s1,s2+s[lf],lf+1,rt)\r\n",
    "            dfs(s1,s2,lf+1,rt)\r\n",
    "        res = 0\r\n",
    "        dfs('','',0,len(s)-1)\r\n",
    "        return res"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maxProduct(self, s: str) -> int:\n",
    "        n = len(s)\n",
    "\n",
    "        def isPalindrome(ls):\n",
    "            l, r = 0, len(ls) - 1\n",
    "            while l < r:\n",
    "                if ls[l] != ls[r]:\n",
    "                    return False\n",
    "                l += 1\n",
    "                r -= 1\n",
    "            return True\n",
    "        \n",
    "        ans = 0\n",
    "        a, b = [], []\n",
    "        \n",
    "        def dfs(i):\n",
    "            nonlocal a, b, ans\n",
    "            if i == n:\n",
    "                if isPalindrome(a) and isPalindrome(b) and len(a) * len(b) > ans:\n",
    "                    ans = len(a) * len(b)\n",
    "                return\n",
    "\n",
    "            dfs(i + 1)\n",
    "\n",
    "            a.append(s[i])\n",
    "            dfs(i + 1)\n",
    "            a = a[:-1]\n",
    "\n",
    "            b.append(s[i])\n",
    "            dfs(i + 1)\n",
    "            b = b[:-1]\n",
    "\n",
    "        dfs(0)\n",
    "\n",
    "        return ans"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maxProduct(self, s: str) -> int:\n",
    "        # 就是你从s中挑出一个回文串\n",
    "        # 然后从剩下的在挑出一个回文串\n",
    "        # 让它们两个的乘积最大\n",
    "        def palindrome(x):\n",
    "            # 求x的最长回文子序列\n",
    "            n = len(x)\n",
    "            dp = [[0]*(n) for _ in range(n)]\n",
    "            for i in range(n-1,-1,-1):\n",
    "                dp[i][i] = 1\n",
    "                for j in range(i+1,n):\n",
    "                    if x[i] == x[j]:\n",
    "                        dp[i][j] = dp[i+1][j-1]+2\n",
    "                    else:\n",
    "                        dp[i][j] = max(dp[i][j-1],dp[i+1][j])\n",
    "            return dp[0][n-1]\n",
    "        # 枚举每种选择\n",
    "        m = len(s)\n",
    "        ans = 0\n",
    "        for i in range(1 << m):\n",
    "            l = ''\n",
    "            r = ''\n",
    "            for j in range(m):\n",
    "                # 如果选择\n",
    "                if i & (1 << j):\n",
    "                    l += s[j]\n",
    "                else:\n",
    "                    r += s[j]\n",
    "            if r == '' or l == '':\n",
    "                continue\n",
    "            ans = max(ans,palindrome(l)*palindrome(r))\n",
    "        return ans"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maxProduct(self, s: str) -> int:\n",
    "        n = len(s)\n",
    "\n",
    "        def check(mask):\n",
    "            ls = []\n",
    "            for i in range(n):\n",
    "                if mask >> i & 1:\n",
    "                    ls.append(s[i])\n",
    "            return ls == ls[::-1]\n",
    "\n",
    "        palindrome_set = set()\n",
    "        for mask in range(2 ** n):\n",
    "            if check(mask):\n",
    "                palindrome_set.add(mask)\n",
    "        \n",
    "        ans = 0\n",
    "        for i in palindrome_set:\n",
    "            for j in palindrome_set:\n",
    "                if i & j == 0:\n",
    "                    ans = max(ans, i.bit_count() * j.bit_count())\n",
    "        return ans\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maxProduct(self, s: str) -> int:\n",
    "        n = len(s)\n",
    "        res = []\n",
    "        for i in range(1, 1<<n):\n",
    "            mid = \"\"\n",
    "            for j in range(n):\n",
    "                if (1<<j) & i :\n",
    "                    mid += s[j]\n",
    "            if mid[::-1] == mid:\n",
    "                res.append(i)\n",
    "        m = len(res)\n",
    "        ans = 0\n",
    "        for i in range(m-1):\n",
    "            for j in range(i+1, m):\n",
    "                if res[i]&res[j] == 0 :\n",
    "                    ans = max(ans, bin(res[i]).count(\"1\")*bin(res[j]).count(\"1\"))\n",
    "        return ans\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maxProduct(self, s: str) -> int:\n",
    "        \n",
    "        n=len(s)\n",
    "        ans=1\n",
    "\n",
    "        def dfs(pos,s1,s2):\n",
    "            nonlocal ans\n",
    "            if pos==n:\n",
    "                if s1==s1[::-1] and s2==s2[::-1]:\n",
    "                    ans=max(ans,len(s1)*len(s2))\n",
    "                return\n",
    "            dfs(pos+1,s1,s2)\n",
    "            dfs(pos+1,s1+s[pos],s2)\n",
    "            dfs(pos+1,s1,s2+s[pos])\n",
    "        dfs(0,'','')\n",
    "        return ans\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maxProduct(self, s: str) -> int:\n",
    "        res = 1\n",
    "        n = len(s)\n",
    "        arr = []\n",
    "\n",
    "        def check(a):\n",
    "            i, j = 0, len(a) - 1\n",
    "            while i < j:\n",
    "                if a[i] != a[j]:\n",
    "                    return False\n",
    "                i += 1\n",
    "                j -= 1\n",
    "            return True\n",
    "\n",
    "        def bit_count(x):\n",
    "            i = 0\n",
    "            while x:\n",
    "                if x & 1: i += 1\n",
    "                x >>= 1\n",
    "            return i\n",
    "\n",
    "        for i in range((1 << n)):\n",
    "            temp = \"\"\n",
    "            j = i\n",
    "            k = 0\n",
    "            while j:\n",
    "                if j & 1:\n",
    "                    temp += s[k]\n",
    "                j >>= 1\n",
    "                k += 1\n",
    "            \n",
    "            if check(temp):\n",
    "                arr.append(i)\n",
    "\n",
    "        for i in range(len(arr)):\n",
    "            for j in range(i + 1, len(arr)):\n",
    "                if (arr[i] & arr[j]) == 0:\n",
    "                    res = max(res, bit_count(arr[i]) * bit_count(arr[j]))\n",
    "\n",
    "        return res\n",
    "\n",
    "        "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "\n",
    "class Solution:\n",
    "    def maxProduct(self, s: str) -> int:\n",
    "        n = len(s)\n",
    "        total = []\n",
    "        for i in range(1<<n):\n",
    "            tmp = \"\"\n",
    "            for j in range(n):\n",
    "                if (1<<j) & i :\n",
    "                    tmp+=s[j]\n",
    "            if tmp == tmp[::-1]:\n",
    "                total.append(i)\n",
    "        ans = 0\n",
    "        for i in range(len(total)):\n",
    "            for j in range(i+1,len(total)):\n",
    "                if (total[i]&total[j]) == 0:\n",
    "                    ans = max(ans,total[i].bit_count()*total[j].bit_count())\n",
    "        return ans "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maxProduct(self, s: str) -> int:\n",
    "        n = len(s)\n",
    "        ans = 1\n",
    "        def check(ss):\n",
    "            return ss == ss[::-1]\n",
    "        @lru_cache\n",
    "        def bk(idx, a, b):\n",
    "            nonlocal ans\n",
    "            if idx == n:\n",
    "                if len(a) * len(b) > ans and check(a) and check(b):\n",
    "                    ans = len(a) * len(b)\n",
    "                return\n",
    "            \n",
    "            bk(idx + 1, a, b)\n",
    "            bk(idx + 1, a + s[idx], b)\n",
    "            bk(idx + 1, a, b + s[idx])\n",
    "        \n",
    "        bk(0, '', '')\n",
    "        bk.cache_clear()\n",
    "        return ans"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maxProduct(self, s: str) -> int:\n",
    "        n = len(s)\n",
    "\n",
    "\n",
    "        def check(mask):\n",
    "            ls = []\n",
    "            for i in range(n):\n",
    "                if mask >> i & 1:\n",
    "                    ls.append(s[i])\n",
    "            return ls == ls[::-1]\n",
    "\n",
    "        palindrome_set = set()\n",
    "        for mask in range(2 ** n):\n",
    "            if check(mask):\n",
    "                palindrome_set.add(mask)\n",
    "        \n",
    "        ans = 0\n",
    "        for i in palindrome_set:\n",
    "            for j in palindrome_set:\n",
    "                if i & j == 0:\n",
    "                    ans = max(ans, i.bit_count() * j.bit_count())\n",
    "        return ans\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maxProduct(self, s: str) -> int:\n",
    "        def isPalindrome(s):\n",
    "            for i in range(len(s)//2):\n",
    "                if s[i] != s[len(s) - 1 - i]:\n",
    "                    return False\n",
    "            return True\n",
    "\n",
    "        # 思路不是很清晰，感觉不是很会！\n",
    "        # 参考网友的回溯做法如下：\n",
    "        def backtrack(pos):\n",
    "            nonlocal ans\n",
    "            if pos == n:\n",
    "                if len(a) * len(b) > ans and isPalindrome(a) and isPalindrome(b):\n",
    "                    ans = len(a) * len(b)\n",
    "                return\n",
    "            # 不选\n",
    "            backtrack(pos + 1)\n",
    "\n",
    "            # 放入a\n",
    "            a.append(s[pos])\n",
    "            backtrack(pos + 1)\n",
    "            a.pop()\n",
    "\n",
    "            # 放入b\n",
    "            b.append(s[pos])\n",
    "            backtrack(pos + 1)\n",
    "            b.pop()\n",
    "\n",
    "        n = len(s)\n",
    "        a,b = [],[]\n",
    "        ans = 0\n",
    "        backtrack(0)\n",
    "        return ans"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maxProduct(self, s: str) -> int:\n",
    "        n = len(s)\n",
    "        ans = 1\n",
    "\n",
    "        @lru_cache\n",
    "        def bk(idx, a, b):\n",
    "            nonlocal ans\n",
    "            if idx == n:\n",
    "                if len(a) * len(b) > ans and a == a[::-1] and b == b[::-1]:\n",
    "                    ans = len(a) * len(b)\n",
    "                return\n",
    "            \n",
    "            bk(idx + 1, a, b)\n",
    "            bk(idx + 1, a + s[idx], b)\n",
    "            bk(idx + 1, a, b + s[idx])\n",
    "        \n",
    "        bk(0, '', '')\n",
    "        bk.cache_clear()\n",
    "        return ans"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maxProduct(self, s: str) -> int:\n",
    "        n=len(s)\n",
    "        total=[] #存放所有回文子序列\n",
    "        for i in range(1,1<<n): #用位运算列出所有子序列\n",
    "            temp=''\n",
    "            for j in range(n):\n",
    "                if (1<<j)&i:\n",
    "                    temp+=s[j]\n",
    "            print(i,temp)\n",
    "            if temp==temp[::-1]: #判断是否为回文\n",
    "                total.append(i)\n",
    "        #用位运算暴力获得所有的子 序列 ！\n",
    "        #apped的是二进制数，并非字符串\n",
    "\n",
    "        def count1(m:int): #统计二进制中1的个数\n",
    "            res=0\n",
    "            while m:\n",
    "                res+=(m&1)\n",
    "                m>>=1\n",
    "            return res\n",
    "        \n",
    "        ret=0\n",
    "        for i in range(len(total)):\n",
    "            for j in range(i+1,len(total)):\n",
    "                if total[i]&total[j]==0:    # total[i]&total[j]为0说明俩子序列不相交\n",
    "                    ret=max(ret,count1(total[i])*count1(total[j])) \n",
    "        return ret                #1的个数表示回文序列的长度，并计算俩长度的乘积"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maxProduct(self, s: str) -> int:\n",
    "        ans = 0\n",
    "        s1 = []\n",
    "        s2 = []\n",
    "        def dfs(i):\n",
    "            nonlocal ans\n",
    "            if i == len(s):\n",
    "                if s1 == s1[: : - 1] and s2 == s2[: : -1]:\n",
    "                    ans = max(ans, len(s1) * len(s2))\n",
    "                return\n",
    "            dfs(i + 1)\n",
    "            s1.append(s[i])\n",
    "            dfs(i + 1)\n",
    "            s1.pop()\n",
    "            s2.append(s[i])\n",
    "            dfs(i + 1)\n",
    "            s2.pop()\n",
    "        \n",
    "        dfs(0)\n",
    "        return ans"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maxProduct(self, s: str) -> int:\n",
    "        masks, n, res = [], len(s), 1\n",
    "\n",
    "        for pre in range(1, 2**n):\n",
    "            tmp = ''.join(s[i] for i in range(n) if pre & (1<<i))\n",
    "            if tmp == tmp[::-1]:\n",
    "                masks.append([pre, len(tmp)])\n",
    "\n",
    "        for i in range(len(masks)):\n",
    "            for j in range(i):\n",
    "                if masks[i][0] & masks[j][0] == 0:\n",
    "                    res = max(res, masks[i][1] * masks[j][1])\n",
    "\n",
    "        return res"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maxProduct(self, s: str) -> int:\n",
    "        n = len(s)\n",
    "        palindromes = []\n",
    "        \n",
    "        # 判断是否是回文\n",
    "        def is_palindrome(mask):\n",
    "            seq = [s[i] for i in range(n) if (mask >> i) & 1]\n",
    "            return seq == seq[::-1]\n",
    "\n",
    "        # 生成所有子序列并保存回文子序列\n",
    "        for mask in range(1, 1 << n):\n",
    "            if is_palindrome(mask):\n",
    "                palindromes.append(mask)\n",
    "\n",
    "        ans = 0\n",
    "        for i in range(len(palindromes)):\n",
    "            for j in range(i+1, len(palindromes)):\n",
    "                # 如果两个子序列不相交\n",
    "                if palindromes[i] & palindromes[j] == 0:\n",
    "                    ans = max(ans, bin(palindromes[i]).count('1') * bin(palindromes[j]).count('1'))\n",
    "        return ans"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maxProduct(self, s: str) -> int:\n",
    "        valid = {}\n",
    "\n",
    "        def check(i):\n",
    "            res = []\n",
    "            for j in range(len(s)):\n",
    "                if i & (1 << j):\n",
    "                    res.append(s[j])\n",
    "\n",
    "            i = 0\n",
    "            j = len(res) - 1\n",
    "\n",
    "            while i < j:\n",
    "                if res[i] != res[j]:\n",
    "                    return False, 0\n",
    "                \n",
    "                i += 1\n",
    "                j -= 1\n",
    "            return True, len(res)\n",
    "\n",
    "        for i in range(1 << len(s)):\n",
    "            flag, size = check(i)\n",
    "            if flag:\n",
    "                valid[i] = size\n",
    "\n",
    "        \n",
    "        key = list(valid.keys())\n",
    "        res = 0\n",
    "        for i in range(len(key)):\n",
    "            for j in range(i + 1, len(key)):\n",
    "                if key[i] & key[j] == 0:\n",
    "                    res = max(res, valid[key[i]] * valid[key[j]])\n",
    "        return res\n",
    "\n",
    "\n",
    "\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maxProduct(self, s: str) -> int:\n",
    "        \n",
    "        n = len(s)\n",
    "        def isPalindrome(s, mask):\n",
    "            ls = []\n",
    "            for i in range(n):\n",
    "                if mask >> i & 1:\n",
    "                    ls.append(s[i])\n",
    "\n",
    "            l, r = 0, len(ls)-1\n",
    "            while l < r:\n",
    "                if ls[l] != ls[r]:\n",
    "                    return False\n",
    "                l += 1\n",
    "                r -= 1\n",
    "            return True\n",
    "        \n",
    "        n = len(s)\n",
    "\n",
    "        candset = set() \n",
    "        for mask in range(2 ** n):\n",
    "            if isPalindrome(s, mask):\n",
    "                candset.add(mask)\n",
    "        \n",
    "        ans = 0\n",
    "        for i in candset:\n",
    "            for j in candset:\n",
    "                if not i & j:\n",
    "                    ans = max(ans, i.bit_count() * j.bit_count())\n",
    "        \n",
    "        return ans"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maxProduct(self, s: str) -> int:\n",
    "        def check(mask):\n",
    "            ans=[]\n",
    "            for j in range(n):\n",
    "                if mask>>j&1: ans.append(s[j])\n",
    "            if ans==ans[::-1]: return len(ans)\n",
    "            return -1\n",
    "        n=len(s)\n",
    "        k=1<<n\n",
    "        f=defaultdict(int)\n",
    "        for i in range(1,k-1):\n",
    "            cur=check(i)\n",
    "            if cur>0: f[i]=cur\n",
    "        #处理出回文子序列\n",
    "        res=1\n",
    "        for i in f:\n",
    "            for j in f:\n",
    "                if i&j==0: res=max(res,f[i]*f[j])\n",
    "        return res"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maxProduct(self, s: str) -> int:\n",
    "        \n",
    "        n = len(s)\n",
    "        def isPalindrome(s, mask):\n",
    "            ls = []\n",
    "            for i in range(n):\n",
    "                if mask >> i & 1:\n",
    "                    ls.append(s[i])\n",
    "\n",
    "            l, r = 0, len(ls)-1\n",
    "            while l < r:\n",
    "                if ls[l] != ls[r]:\n",
    "                    return False\n",
    "                l += 1\n",
    "                r -= 1\n",
    "            return True\n",
    "        \n",
    "        candset = set() \n",
    "        for mask in range(2 ** n):\n",
    "            if isPalindrome(s, mask):\n",
    "                candset.add(mask)\n",
    "        \n",
    "        ans = 0\n",
    "        for i in candset:\n",
    "            for j in candset:\n",
    "                if not i & j:\n",
    "                    ans = max(ans, i.bit_count() * j.bit_count())\n",
    "        \n",
    "        return ans"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maxProduct(self, s: str) -> int:\n",
    "        n=len(s)\n",
    "        total=[] #存放所有回文子序列\n",
    "        for i in range(1,1<<n): #用位运算列出所有子序列\n",
    "            temp=''\n",
    "            for j in range(n):\n",
    "                if (1<<j)&i:\n",
    "                    temp+=s[j]\n",
    "            if temp==temp[::-1]: #判断是否为回文\n",
    "                total.append(i)\n",
    "        \n",
    "        def count1(m:int): #统计二进制中1的个数\n",
    "            res=0\n",
    "            while m:\n",
    "                res+=(m&1)\n",
    "                m>>=1\n",
    "            return res\n",
    "        \n",
    "        ret=0\n",
    "        for i in range(len(total)):\n",
    "            for j in range(i+1,len(total)):\n",
    "                if total[i]&total[j]==0:    # total[i]&total[j]为0说明俩子序列不相交\n",
    "                    ret=max(ret,count1(total[i])*count1(total[j])) \n",
    "        return ret                #1的个数表示回文序列的长度，并计算俩长度的乘积\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maxProduct(self, s: str) -> int:\n",
    "        n=len(s)\n",
    "        ls=[]\n",
    "        for i in range(1,1<<n):\n",
    "            tp=[]\n",
    "            for j in range(n):\n",
    "                if i&(1<<j):\n",
    "                    tp.append(s[j])\n",
    "            if  tp==tp[::-1]:\n",
    "                ls.append(i)\n",
    "        def count1(x):\n",
    "            c=0\n",
    "            while x:\n",
    "                c+=(x&1)\n",
    "                x>>=1\n",
    "            return c\n",
    "        ans=0\n",
    "        m=len(ls)\n",
    "        for i in range(m):\n",
    "            for j in range(i+1,m):\n",
    "                if ls[i]&ls[j]==0:\n",
    "                    ans=max(ans,count1(ls[i])*count1(ls[j]))\n",
    "        return ans"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maxProduct(self, s: str) -> int:\n",
    "        # 基本思路: 求出每一个字符串的位图表示和长度的map\n",
    "        # 根据位图计算是否是相交\n",
    "        N = len(s)\n",
    "        pali = {}\n",
    "        for mask in range(1, 1 << N):\n",
    "            subSeq = ''\n",
    "            for i in range(N):\n",
    "                if (mask & (1 << i)):\n",
    "                    subSeq += s[i]\n",
    "            if subSeq == subSeq[::-1]:\n",
    "                pali[mask] = len(subSeq)\n",
    "        res = 0\n",
    "        for m1,l1 in pali.items():\n",
    "            for m2, l2 in pali.items():\n",
    "                if m1 & m2 == 0:\n",
    "                    res = max(res,l1 * l2 )\n",
    "        return res"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maxProduct(self, s: str) -> int:\n",
    "        valid = {}\n",
    "\n",
    "        def check(i):\n",
    "            res = []\n",
    "            for j in range(len(s)):\n",
    "                if i & (1 << j):\n",
    "                    res.append(s[j])\n",
    "\n",
    "            i = 0\n",
    "            j = len(res) - 1\n",
    "\n",
    "            while i < j:\n",
    "                if res[i] != res[j]:\n",
    "                    return False, 0\n",
    "                \n",
    "                i += 1\n",
    "                j -= 1\n",
    "            return True, len(res)\n",
    "\n",
    "        for i in range(1, 1 << len(s)):\n",
    "            flag, size = check(i)\n",
    "            if flag:\n",
    "                valid[i] = size\n",
    "\n",
    "        \n",
    "        key = list(valid.keys())\n",
    "        res = 0\n",
    "        for i in range(len(key)):\n",
    "            for j in range(i + 1, len(key)):\n",
    "                if key[i] & key[j] == 0:\n",
    "                    res = max(res, valid[key[i]] * valid[key[j]])\n",
    "        return res\n",
    "\n",
    "\n",
    "\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maxProduct(self, s: str) -> int:\n",
    "\n",
    "        # 1. 首先记录所有的回文子序列（保存其长度即可）及其对应的 mask\n",
    "        \n",
    "        n = len(s)\n",
    "        pairs = []  # (回文子序列长度，回文子序列对应的 mask)\n",
    "        \n",
    "        # 二进制枚举子序列\n",
    "        for mask in range(1, 1 << n):\n",
    "            mask_t = mask   # 暂存当前子序列的 mask\n",
    "            seqs = []\n",
    "            for i in range(n):\n",
    "                if mask & 1:\n",
    "                    seqs.append(s[i])\n",
    "                mask >>= 1\n",
    "            \n",
    "            # 如果当前子序列是回文子序列，\n",
    "            # 则存其长度及其对应的 mask\n",
    "            if seqs == seqs[::-1]:\n",
    "                pairs.append((len(seqs), mask_t))\n",
    "\n",
    "\n",
    "        # 2. 然后求两个不相交回文子序列长度的乘积最大值\n",
    "\n",
    "        m = len(pairs)\n",
    "        res = 0\n",
    "\n",
    "        for i in range(m):\n",
    "            for j in range(i + 1, m):\n",
    "                len1, mask1 = pairs[i]\n",
    "                len2, mask2 = pairs[j]\n",
    "                \n",
    "                # 判断两个回文子序列是否相交\n",
    "                if mask1 & mask2 == 0:\n",
    "                    res = max(res, len1 * len2)\n",
    "        \n",
    "        return res"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maxProduct(self, s: str) -> int:\n",
    "        def check(mask):\n",
    "            ans=[]\n",
    "            for j in range(n):\n",
    "                if mask>>j&1: ans.append(s[j])\n",
    "            if ans==ans[::-1]: return len(ans)\n",
    "            return -1\n",
    "        n=len(s)\n",
    "        k=1<<n\n",
    "        f=dict()\n",
    "        for i in range(1,k-1):\n",
    "            cur=check(i)\n",
    "            if cur>0: f[i]=cur\n",
    "        #处理出回文子序列\n",
    "        res=1\n",
    "        for i in f:\n",
    "            for j in f:\n",
    "                if i&j==0: res=max(res,f[i]*f[j])\n",
    "        return res"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maxProduct(self, s: str) -> int:\n",
    "        masks, n, res = [], len(s), 1\n",
    "\n",
    "        for pre in range(1, 2**n):\n",
    "            tmp = [s[i] for i in range(n) if pre & (1<<i)]\n",
    "            if tmp == tmp[::-1]:\n",
    "                masks.append([pre, len(tmp)])\n",
    "\n",
    "        for i in range(len(masks)):\n",
    "            for j in range(i):\n",
    "                if masks[i][0] & masks[j][0] == 0:\n",
    "                    res = max(res, masks[i][1] * masks[j][1])\n",
    "\n",
    "        return res"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maxProduct(self, s: str) -> int:\n",
    "        #状态压缩+位运算+暴力搜索(优化后的)\n",
    "        #这题不用DP\n",
    "        def check(mask):\n",
    "            ans=[]\n",
    "            for j in range(n):\n",
    "                if mask>>j&1: ans.append(s[j])\n",
    "            if ans==ans[::-1]: return len(ans)\n",
    "            return -1\n",
    "        n=len(s)\n",
    "        k=1<<n\n",
    "        f=dict()\n",
    "        for i in range(1,k-1):\n",
    "            cur=check(i)\n",
    "            if cur>0: f[i]=cur\n",
    "        #处理出回文子序列\n",
    "        res=1\n",
    "        for i in f:\n",
    "            for j in f:\n",
    "                if i&j==0: res=max(res,f[i]*f[j])\n",
    "        return res"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maxProduct(self, s: str) -> int:\n",
    "        n=len(s)\n",
    "        length=1<<n\n",
    "        \n",
    "        def check(state):\n",
    "            left=0\n",
    "            right=n-1\n",
    "            while left<right:\n",
    "                while left<right and (state>>left)&1==0:\n",
    "                    left+=1\n",
    "                while left<right and (state>>right)&1==0:\n",
    "                    right-=1\n",
    "                if s[left]!=s[right]:\n",
    "                    return False\n",
    "                left+=1\n",
    "                right-=1\n",
    "            return True\n",
    "\n",
    "        def Countbin(x):\n",
    "            temp=str(bin(x))[2:]\n",
    "            cnt=0\n",
    "            for i in range(len(temp)):\n",
    "                if temp[i]=='1':\n",
    "                    cnt+=1\n",
    "            return cnt\n",
    "        #遍历所有状态\n",
    "        arr=[]\n",
    "        for i in range(length):\n",
    "            if check(i):\n",
    "                arr.append([i, Countbin(i)])\n",
    "        ans=0\n",
    "        for i in range(len(arr)):\n",
    "            x1=arr[i][0]\n",
    "            len1=arr[i][1]\n",
    "            for j in range(i+1, len(arr)):\n",
    "                x2=arr[j][0]\n",
    "                len2=arr[j][1]\n",
    "                if x1&x2==0:\n",
    "                    ans=max(ans, len1*len2)\n",
    "        return ans\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maxProduct(self, s: str) -> int:\n",
    "        masks, n, res = [], len(s), 1\n",
    "        print(s)\n",
    "        import time\n",
    "        t1 = time.time()\n",
    "\n",
    "        for pre in range(1, 2**n):\n",
    "            tmp = ''.join(s[i] for i in range(n) if pre & (1<<i))\n",
    "            \n",
    "            if tmp == tmp[::-1]:\n",
    "                #print(pre, bin(pre)[2:], '-> ', tmp)\n",
    "                masks.append([pre, tmp])\n",
    "\n",
    "        print(len(masks))\n",
    "        #print(masks)\n",
    "\n",
    "        t2 = time.time()\n",
    "\n",
    "        for i in range(len(masks)):\n",
    "            for j in range(i):\n",
    "                if masks[i][0] & masks[j][0] == 0:\n",
    "                    #print(masks[i], masks[j])\n",
    "                    res = max(res, len(masks[i][1]) * len(masks[j][1]))\n",
    "\n",
    "        t3 = time.time()\n",
    "\n",
    "        print(t2 - t1 , t3 - t2)\n",
    "\n",
    "        return res\n",
    "\n",
    "  "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maxProduct(self, s: str) -> int:\n",
    "        import bisect\n",
    "        allres = []\n",
    "        n = len(s)\n",
    "        for i in range(1,1<<n):\n",
    "            temp = \"\"\n",
    "            for j in range(n):\n",
    "                if i & (1<<j):\n",
    "                    temp += s[j]\n",
    "            if temp == temp[::-1]:\n",
    "                bisect.insort(allres,(temp,i),key=lambda x:len(x[0]))\n",
    "        res = 0\n",
    "        for x,i in allres:\n",
    "            for y,j in allres:\n",
    "                if i & j == 0:\n",
    "                    res = max(res,len(x)*len(y))\n",
    "        return res\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maxProduct(self, s: str) -> int:\n",
    "        n = len(s)\n",
    "        collector = list()\n",
    "\n",
    "        def dfs(i, num=0, t=\"\"):\n",
    "            if i == n:\n",
    "                if t == t[::-1]:\n",
    "                    collector.append((num, len(t)))\n",
    "                return\n",
    "            dfs(i+1, num*2, t)\n",
    "            dfs(i+1, num*2+1, t+s[i])\n",
    "\n",
    "        dfs(0)\n",
    "        n = len(collector)\n",
    "        result = 0\n",
    "        for i in range(n):\n",
    "            for j in range(i+1, n):\n",
    "                t1, t2 = collector[i], collector[j]\n",
    "                if t1[0] & t2[0] == 0:\n",
    "                    result = max(result, t1[1]*t2[1])\n",
    "        return result\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maxProduct(self, s: str) -> int:\n",
    "        ret = []\n",
    "\n",
    "        def dfs(t, step):\n",
    "            if step == len(s):\n",
    "                tmp, cnt, g = [], 0, t\n",
    "                while g:\n",
    "                    if g & 1: tmp.append(cnt)\n",
    "                    cnt += 1\n",
    "                    g //= 2\n",
    "                cnt = 0\n",
    "                while tmp and cnt <= len(tmp) // 2:\n",
    "                    if s[tmp[cnt]] != s[tmp[len(tmp) - 1 - cnt]]: return\n",
    "                    cnt += 1\n",
    "                if tmp: ret.append(t)\n",
    "                return\n",
    "            dfs(t, step + 1)\n",
    "            dfs(t | (1 << step), step + 1)\n",
    "\n",
    "        dfs(0, 0)\n",
    "        ans = 0\n",
    "        for i in range(len(ret)):\n",
    "            for j in range(1, len(ret)):\n",
    "                if ret[i] & ret[j] == 0:\n",
    "                    cnt, g = 0, ret[i]\n",
    "                    while g:\n",
    "                        if g & 1: cnt += 1\n",
    "                        g //= 2\n",
    "                    cnt2, g2 = 0, ret[j]\n",
    "                    while g2:\n",
    "                        if g2 & 1: cnt2 += 1\n",
    "                        g2 //= 2\n",
    "                    ans = max(ans, cnt * cnt2)\n",
    "        return ans"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    # eecc odo为何不可\n",
    "    def maxProduct(self, s: str) -> int:\n",
    "        answer = 1\n",
    "        total_index = {i for i in range(len(s))}\n",
    "        for i in range(1, 2 ** len(s)):\n",
    "            # 应该立即排除某些位数为1的情况。需要反转字符串\n",
    "            bin_str1 = bin(i).replace(\"0b\", \"\")[::-1]\n",
    "            # 找到它为1的索引\n",
    "            one_index = {i for i in range(len(bin_str1)) if bin_str1[i] == \"1\"}\n",
    "            two_index = sorted(list(total_index - one_index))\n",
    "            one_index = sorted(list(one_index))\n",
    "            # 注意set是无序集合\n",
    "            if not self.match([s[i] for i in one_index]):\n",
    "                continue\n",
    "            result_index = self.back_trace(0, [], two_index)\n",
    "            for single in result_index:\n",
    "                if not self.match([s[i] for i in single]):\n",
    "                    continue\n",
    "                # 两个都是回文串时\n",
    "                answer = max(answer, len(one_index) * len(single))\n",
    "        return answer\n",
    "\n",
    "    def match(self, s: []) -> bool:\n",
    "        \"\"\"\n",
    "        判断一个字符串是否是回文串\n",
    "        :param s:\n",
    "        :return:\n",
    "        \"\"\"\n",
    "        n = len(s)\n",
    "        for i in range(n // 2):\n",
    "            if s[i] != s[n - i - 1]:\n",
    "                return False\n",
    "        return True\n",
    "\n",
    "    def back_trace(self, start: int, index_list: list, source_index: list) -> list:\n",
    "        answer = []\n",
    "        for i in range(start, len(source_index)):\n",
    "            list_one = index_list.copy()\n",
    "            list_one.append(source_index[i])\n",
    "            answer.append(list_one)\n",
    "            answer.extend(self.back_trace(i + 1, list_one, source_index))\n",
    "        return answer"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maxProduct(self, s: str) -> int:\n",
    "        n = len(s)\n",
    "        arr = [list() for _ in range(n)]\n",
    "        def judge(arr_s: List[str]) -> bool:\n",
    "            m = len(arr_s)\n",
    "            if m == 0: return False\n",
    "            l, r = 0, m - 1\n",
    "            while l < r:\n",
    "                if arr_s[l][1] != arr_s[r][1]: return False\n",
    "                l += 1\n",
    "                r -= 1\n",
    "            return True\n",
    "        def dfs(index: int, arr_s: List[str], step: int, target: int) -> None:\n",
    "            if judge(arr_s):\n",
    "                arr[target].append(arr_s[:])\n",
    "            for i in range(step, n):\n",
    "                arr_s.append((i, s[i]))\n",
    "                dfs(index + 1, arr_s, i + 1, i if index == 0 else target)\n",
    "                arr_s.pop()\n",
    "        dfs(0, [], 0, 0)\n",
    "        for i in range(n):\n",
    "            for k in range(len(arr[i])):\n",
    "                num = 0\n",
    "                for j in range(len(arr[i][k])):\n",
    "                    num |= 1 << arr[i][k][j][0]\n",
    "                arr[i][k] = (num, len(arr[i][k]))\n",
    "        ans = -1\n",
    "        for i in range(n):\n",
    "            for k in arr[i]:\n",
    "                for j in range(i + 1, n):\n",
    "                    for t in arr[j]:\n",
    "                        if k[0] & t[0] == 0:\n",
    "                            ans = max(ans, k[1] * t[1])\n",
    "        return ans"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\r\n",
    "    def maxProduct(self, s: str) -> int:\r\n",
    "        # 暴力吗， 只有 12 欸 \r\n",
    "        # 暴力思路是，枚举每个字符在哪个集合 , 然后每个集合内求一个最长回文子序列 相乘就好了 \r\n",
    "        # 时间复杂度是 O(2^n)*n^2\r\n",
    "\r\n",
    "        a = []\r\n",
    "        b = []\r\n",
    "        res = 0\r\n",
    "\r\n",
    "        # 返回最长回文子序列 \r\n",
    "        def solve(arr:List[str]) -> int:\r\n",
    "            # 也就是求arr 和 arr[::-1] 的最长公共子序列 \r\n",
    "            s = \"\".join(arr)\r\n",
    "            t = \"\".join(arr[::-1])\r\n",
    "            @cache\r\n",
    "            def lcs(i: int, j: int):\r\n",
    "                if i == 0 or j == 0:\r\n",
    "                    return 0 \r\n",
    "                if s[i - 1] == t[j - 1]:\r\n",
    "                    return lcs(i - 1, j - 1) + 1\r\n",
    "                return max(lcs(i - 1, j), lcs(i, j - 1))\r\n",
    "            return lcs(len(s), len(t))\r\n",
    "        def dfs(i: int):\r\n",
    "            nonlocal res \r\n",
    "            if i == len(s):\r\n",
    "                res = max(res, solve(a) * solve(b))\r\n",
    "                return \r\n",
    "            a.append(s[i])\r\n",
    "            dfs(i + 1)\r\n",
    "            a.pop()\r\n",
    "            b.append(s[i])\r\n",
    "            dfs(i + 1)\r\n",
    "            b.pop()\r\n",
    "        dfs(0)\r\n",
    "        return res "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maxProduct(self, s: str) -> int:\n",
    "        n = len(s)\n",
    "        cnt = Counter(s)\n",
    "        ans = 0\n",
    "        res = set()\n",
    "        def dfs(index,a,stack):\n",
    "            if index == n:\n",
    "                if a and a == a[::-1]:\n",
    "                    res.add(tuple(stack[:]))\n",
    "                return\n",
    "            for i in range(index,n):\n",
    "                dfs(i+1,a+s[i],stack+[i])\n",
    "                dfs(i+1,a,stack)\n",
    "        dfs(0,'',[])\n",
    "        nums = []\n",
    "        for a in res:\n",
    "            nums.append([len(a),set(a)])\n",
    "        nums.sort(key=lambda x:(-x[0]))\n",
    "        #print(nums)\n",
    "        n = len(nums)\n",
    "        for i in range(n):\n",
    "            a_size,a = nums[i]\n",
    "            for j in range(i+1,n):\n",
    "                #if i == j:\n",
    "                #    continue\n",
    "                b_size,b = nums[j]\n",
    "                if a_size*b_size <= ans:break\n",
    "                if len(a-b) == a_size:\n",
    "                    ans = max(ans,a_size*b_size)\n",
    "        return ans\n",
    "                    "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maxProduct(self, s: str) -> int:\n",
    "        n = len(s)\n",
    "        cnt = Counter(s)\n",
    "        ans = 0\n",
    "        res = set()\n",
    "        def dfs(index,a,stack):\n",
    "            if index == n:\n",
    "                if a and a == a[::-1]:\n",
    "                    res.add(tuple(stack[:]))\n",
    "                return\n",
    "            for i in range(index,n):\n",
    "                dfs(i+1,a+s[i],stack+[i])\n",
    "                dfs(i+1,a,stack)\n",
    "        dfs(0,'',[])\n",
    "        nums = []\n",
    "        for a in res:\n",
    "            nums.append([len(a),set(a)])\n",
    "        nums.sort(key=lambda x:(-x[0]))\n",
    "        #print(nums)\n",
    "        n = len(nums)\n",
    "        for i in range(n):\n",
    "            a_size,a = nums[i]\n",
    "            for j in range(n):\n",
    "                if i == j:\n",
    "                    continue\n",
    "                b_size,b = nums[j]\n",
    "                if a_size*b_size <= ans:break\n",
    "                if len(a-b) == a_size:\n",
    "                    ans = max(ans,a_size*b_size)\n",
    "        return ans\n",
    "                    "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "from collections import deque\n",
    "class Solution:\n",
    "    def search_palindromic(self, s):\n",
    "        candidates = []\n",
    "        idxes = []\n",
    "        n = len(s)\n",
    "        occur_dict = {}\n",
    "        for i in range(n):\n",
    "            if s[i] not in occur_dict:\n",
    "                occur_dict[s[i]] = [i]\n",
    "            else:\n",
    "                occur_dict[s[i]].append(i)\n",
    "        seen = set()\n",
    "        seen_idx = set()\n",
    "        def dfs(left, right, current, idx):\n",
    "            if left < 0 or right >= n:\n",
    "                if idx and idx not in seen_idx:\n",
    "                    seen_idx.add(idx)\n",
    "                    candidates.append(current)\n",
    "                    idxes.append(idx)\n",
    "                return \n",
    "            if (left, right, idx) in seen:\n",
    "                return\n",
    "            else:\n",
    "                seen.add((left, right, idx))\n",
    "            # if max(occur_dict[s[left]]) < right:\n",
    "            #     for i in range(left-1, -2, -1):\n",
    "            #         dfs(i, right, current, idx)\n",
    "            # else:\n",
    "            #     for j in occur_dict[s[left]]:\n",
    "            #         if j > right:\n",
    "            #             dfs(left-1, j+1, s[left]+current+s[j], str(left)+\",\"+idx+\",\"+str(j))\n",
    "            #     dfs(left-1, right, current, idx)\n",
    "            if max(occur_dict[s[left]]) >= right:\n",
    "                for j in occur_dict[s[left]]:\n",
    "                    if j >= right:\n",
    "                        dfs(left-1, j+1, s[left]+current+s[j], str(left)+\",\"+idx+\",\"+str(j))\n",
    "            dfs(left-1, right, current, idx)\n",
    "        for i in range(n):\n",
    "            if i-1 >= 0 and s[i-1] == s[i]:\n",
    "                dfs(i-2, i+1, s[i-1:i+1], str(i-1)+\",\"+str(i))\n",
    "            elif i+1 < n and s[i+1] == s[i]:\n",
    "                dfs(i-1, i+2, s[i:i+2], str(i)+\",\"+str(i+1))\n",
    "            dfs(i-1, i+1, s[i], str(i))\n",
    "            dfs(i-1, i+1, \"\", \"\")\n",
    "        # print(seen)\n",
    "        return candidates, idxes, seen_idx\n",
    "\n",
    "    def maxProduct(self, s: str) -> int:\n",
    "        candidates, idxes, seen_idx = self.search_palindromic(s)\n",
    "        # print(candidates, len(candidates))\n",
    "        # print(idxes, len(idxes))\n",
    "        idxes.sort(key=lambda x:len(x),reverse=True)\n",
    "        n = len(idxes)\n",
    "        res = -1\n",
    "        find = False\n",
    "        for i in range(n):\n",
    "            idxes[i] = set(idxes[i].split(','))\n",
    "            if \"\" in idxes[i]:\n",
    "                idxes[i].remove(\"\")\n",
    "        for i in range(n):\n",
    "            for j in range(i+1, n):\n",
    "                temp_1 = idxes[i]\n",
    "                temp_2 = idxes[j]\n",
    "                if not (temp_1 & temp_2):\n",
    "                    # print(temp_1, temp_2)\n",
    "                    res = max(len(temp_1) * len(temp_2), res)\n",
    "        return res\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maxProduct(self, s: str) -> int:\n",
    "\n",
    "        n = len(s)\n",
    "        span = [0] * n\n",
    "        l, r = 0, -1\n",
    "\n",
    "        for i in range(n):\n",
    "            span[i] = (min(span[l + r - i], r - i + 1) if i <= r else 1)\n",
    "            while i - span[i] >= 0 and i + span[i] < n and s[i - span[i]] == s[i + span[i]]:\n",
    "                span[i] += 1\n",
    "            if i + span[i] - 1 > r:\n",
    "                l = i - span[i] + 1\n",
    "                r = i + span[i] - 1\n",
    "\n",
    "        pre, suf = [0] * n, [0] * n\n",
    "        for i in range(n):\n",
    "            pre[i + span[i] - 1] = max(pre[i + span[i] - 1], span[i] * 2 - 1)\n",
    "            suf[i - span[i] + 1] = max(suf[i - span[i] + 1], span[i] * 2 - 1)\n",
    "        \n",
    "        for i in range(1, n):\n",
    "            pre[i] = max(pre[i], pre[i - 1])\n",
    "        for i in range(n - 2, -1, -1):\n",
    "            pre[i] = max(pre[i], pre[i + 1] - 2)\n",
    "        for i in range(n - 2, -1, -1):\n",
    "            suf[i] = max(suf[i], suf[i + 1])\n",
    "        for i in range(1, n):\n",
    "            suf[i] = max(suf[i], suf[i - 1] - 2)\n",
    "\n",
    "        ans = max(pre[i] * suf[i + 1] for i in range(n - 1))\n",
    "        return ans\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maxProduct(self, s: str) -> int:\n",
    "        n = len(s)\n",
    "        span = [0] * n\n",
    "        l, r = 0, -1\n",
    "\n",
    "        for i in range(n):\n",
    "            span[i] = (min(span[l + r - i], r - i + 1) if i <= r else 1)\n",
    "            while i - span[i] >= 0 and i + span[i] < n and s[i - span[i]] == s[i + span[i]]:\n",
    "                span[i] += 1\n",
    "            if i + span[i] - 1 > r:\n",
    "                l = i - span[i] + 1\n",
    "                r = i + span[i] - 1\n",
    "\n",
    "        pre, suf = [0] * n, [0] * n\n",
    "        for i in range(n):\n",
    "            pre[i + span[i] - 1] = max(pre[i + span[i] - 1], span[i] * 2 - 1)\n",
    "            suf[i - span[i] + 1] = max(suf[i - span[i] + 1], span[i] * 2 - 1)\n",
    "        \n",
    "        for i in range(1, n):\n",
    "            pre[i] = max(pre[i], pre[i - 1])\n",
    "        for i in range(n - 2, -1, -1):\n",
    "            pre[i] = max(pre[i], pre[i + 1] - 2)\n",
    "        for i in range(n - 2, -1, -1):\n",
    "            suf[i] = max(suf[i], suf[i + 1])\n",
    "        for i in range(1, n):\n",
    "            suf[i] = max(suf[i], suf[i - 1] - 2)\n",
    "\n",
    "        ans = max(pre[i] * suf[i + 1] for i in range(n - 1))\n",
    "        return ans\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maxProduct(self, s: str) -> int:\n",
    "        def oddmanacher(s):\n",
    "            n = len(s)\n",
    "            d = [0] * n\n",
    "            l, r = 0, -1\n",
    "            for i in range(n):\n",
    "                k = (min(d[l + r - i], r - i + 1) if i <= r else 1)\n",
    "                while i - k >= 0 and i + k < n and s[i - k] == s[i + k]:\n",
    "                    k += 1\n",
    "                d[i] = k\n",
    "                k -= 1\n",
    "                if i + k > r:\n",
    "                    l = i - k\n",
    "                    r = i + k\n",
    "            return d\n",
    "        p=oddmanacher(s)\n",
    "        n=len(s)\n",
    "        pe=[0]*n\n",
    "        sf=[0]*n\n",
    "        for i in range(n):\n",
    "            v=p[i]\n",
    "            pe[i+v-1]=max(pe[i+v-1],2*v-1)\n",
    "            sf[i-v+1]=max(sf[i-v+1],2*v-1)\n",
    "        for i in range(1,n):\n",
    "            pe[i]=max(pe[i],pe[i-1])\n",
    "        for i in range(n-2,-1,-1):\n",
    "            pe[i]=max(pe[i],pe[i+1]-2)\n",
    "        for i in range(n-2,-1,-1):\n",
    "            sf[i]=max(sf[i],sf[i+1])\n",
    "        for i in range(1,n):\n",
    "            sf[i]=max(sf[i],sf[i-1]-2)\n",
    "        ans=0\n",
    "        for i in range(n-1):\n",
    "            ans=max(ans, pe[i]*sf[i+1])\n",
    "        return ans"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maxProduct(self, s: str) -> int:\n",
    "        #copy zero\n",
    "        n = len(s)\n",
    "        span  = [0] * n\n",
    "        l,r = 0,-1\n",
    "\n",
    "        for i in range(n):\n",
    "            span[i] = (min(span[l+r-i],r-i+1) if i <= r else 1)\n",
    "            while i - span[i] >= 0 and i + span[i]<n and s[i-span[i]] == s[i+ span[i]]:\n",
    "                span[i] += 1\n",
    "            if i + span[i]-1>r:\n",
    "                l = i-span[i]+1\n",
    "                r = i + span[i]-1\n",
    "        \n",
    "        pre,suf= [0]*n,[0]*n\n",
    "        for i in range(n):\n",
    "            pre[i+span[i]-1]= max(pre[i+span[i]-1],span[i]*2-1)\n",
    "            suf[i-span[i]+1] = max(suf[i-span[i]+1],span[i]*2-1)\n",
    "\n",
    "        for i in range(1,n):\n",
    "            pre[i] = max(pre[i],pre[i-1])\n",
    "        for i in range(n-2,-1,-1):\n",
    "            pre[i] = max(pre[i],pre[i+1]-2)\n",
    "        for i in range(n-2,-1,-1):\n",
    "            suf[i] = max(suf[i],suf[i+1])\n",
    "        for i in range(1,n):\n",
    "            suf[i] = max(suf[i],suf[i-1]-2)\n",
    "        \n",
    "        ans = max(pre[i]*suf[i+1] for i in range(n-1))\n",
    "        return ans\n",
    "            \n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maxProduct(self, s: str) -> int:\n",
    "        def oddmanacher(s):\n",
    "            n = len(s)\n",
    "            d = [0] * n\n",
    "            l, r = 0, -1\n",
    "            for i in range(n):\n",
    "                k = (min(d[l + r - i], r - i + 1) if i <= r else 1)\n",
    "                while i - k >= 0 and i + k < n and s[i - k] == s[i + k]:\n",
    "                    k += 1\n",
    "                d[i] = k\n",
    "                k -= 1\n",
    "                if i + k > r:\n",
    "                    l = i - k\n",
    "                    r = i + k\n",
    "            return d\n",
    "        p=oddmanacher(s)\n",
    "        n=len(s)\n",
    "        pe=[0]*n\n",
    "        sf=[0]*n\n",
    "        for i in range(n):\n",
    "            v=p[i]\n",
    "            pe[i+v-1]=max(pe[i+v-1],2*v-1)\n",
    "            sf[i-v+1]=max(sf[i-v+1],2*v-1)\n",
    "        for i in range(1,n):\n",
    "            pe[i]=max(pe[i],pe[i-1])\n",
    "        for i in range(n-2,-1,-1):\n",
    "            pe[i]=max(pe[i],pe[i+1]-2)\n",
    "        for i in range(n-2,-1,-1):\n",
    "            sf[i]=max(sf[i],sf[i+1])\n",
    "        for i in range(1,n):\n",
    "            sf[i]=max(sf[i],sf[i-1]-2)\n",
    "        ans=0\n",
    "        for i in range(n-1):\n",
    "            ans=max(ans, pe[i]*sf[i+1])\n",
    "        return ans"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maxProduct(self, s: str) -> int:\n",
    "        # 这个只要求是奇数回文串，甚至还是比较简单的马拉车\n",
    "        def manacher(s):\n",
    "            n = len(s)\n",
    "            l = r = c = 0\n",
    "            dp = [0] * n\n",
    "            right_max = [1] * n\n",
    "            for i, ch in enumerate(s):\n",
    "                mirror_i = 2 * c - i\n",
    "                r0 = max(0, min(r-i, dp[mirror_i]))\n",
    "                while i-r0-1 >= 0 and i+r0+1 < n and s[i-r0-1]==s[i+r0+1]:\n",
    "                    r0 += 1\n",
    "                    right_max[i+r0] = max(right_max[i+r0], 2*r0+1)\n",
    "                dp[i] = r0\n",
    "                if i+r0 > r:\n",
    "                    l, r, c = i-r0, i+r0, i\n",
    "            return right_max\n",
    "        \n",
    "        left = manacher(s[::-1])[::-1]\n",
    "        right = manacher(s)\n",
    "        ans = 0\n",
    "        n = len(s)\n",
    "        for i in range(n-2, -1, -1):\n",
    "            left[i] = max(left[i], left[i+1])\n",
    "        for i in range(n-1):\n",
    "            right[i+1] = max(right[i+1], right[i])\n",
    "            ans = max(right[i] * left[i+1], ans)\n",
    "        \n",
    "        return ans\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class ManacherPlindrome:\n",
    "    def __init__(self):\n",
    "        return\n",
    "\n",
    "    @staticmethod\n",
    "    def max(a, b):\n",
    "        return a if a > b else b\n",
    "\n",
    "    @staticmethod\n",
    "    def manacher(s):\n",
    "        # 马拉车算法\n",
    "        n = len(s)\n",
    "        arm = [0] * n\n",
    "        left, right = 0, -1\n",
    "        for i in range(0, n):\n",
    "            a, b = arm[left + right - i], right - i + 1\n",
    "            a = a if a < b else b\n",
    "            k = 1 if i > right else a\n",
    "\n",
    "            # 持续增加回文串的长度\n",
    "            while 0 <= i - k and i + k < n and s[i - k] == s[i + k]:\n",
    "                k += 1\n",
    "            arm[i] = k\n",
    "\n",
    "            # 更新右侧最远的回文串边界\n",
    "            k -= 1\n",
    "            if i + k > right:\n",
    "                left = i - k\n",
    "                right = i + k\n",
    "        # 返回每个位置往右的臂长其中 s[i-arm[i]+1: i+arm[i]] 为回文子串范围\n",
    "        # 即以i为中心的最长回文子串长度\n",
    "        return arm\n",
    "\n",
    "    def palindrome(self, s: str) -> (list, list):\n",
    "        # 获取区间的回文串信息\n",
    "        n = len(s)\n",
    "        # 保证所有的回文串为奇数长度，且中心为 # 的为原偶数回文子串，中心为 字母 的为原奇数回文子串\n",
    "        t = \"#\" + \"#\".join(list(s)) + \"#\"\n",
    "        dp = self.manacher(t)\n",
    "        m = len(t)\n",
    "\n",
    "        # 以当前索引作为边界开头的回文子串结束位置索引\n",
    "        start = [[] for _ in range(n)]\n",
    "        # 以当前索引作为边界结尾的回文子串起始位置索引\n",
    "        end = [[] for _ in range(n)]\n",
    "\n",
    "        for j in range(m):\n",
    "            left = j - dp[j] + 1\n",
    "            right = j + dp[j] - 1\n",
    "            while left <= right:\n",
    "                if t[left] != \"#\":\n",
    "                    start[left // 2].append(right // 2)\n",
    "                    end[right//2].append(left//2)\n",
    "                left += 1\n",
    "                right -= 1\n",
    "        return start, end\n",
    "\n",
    "    def palindrome_longest(self, s: str) -> (list, list):\n",
    "        # 获取区间的回文串信息\n",
    "        n = len(s)\n",
    "        # 保证所有的回文串为奇数长度，且中心为 # 的为原偶数回文子串，中心为 字母 的为原奇数回文子串\n",
    "        t = \"#\" + \"#\".join(list(s)) + \"#\"\n",
    "        dp = self.manacher(t)\n",
    "        m = len(t)\n",
    "\n",
    "        # 由此还可以获得以某个位置开头或者结尾的最长回文子串的长度\n",
    "        post = [1] * n\n",
    "        pre = [1] * n\n",
    "\n",
    "        for j in range(m):\n",
    "            left = j - dp[j] + 1\n",
    "            right = j + dp[j] - 1\n",
    "            while left <= right:\n",
    "                if t[left] != \"#\":\n",
    "                    x, y = left // 2, right // 2\n",
    "                    post[x] = self.max(post[x], y - x + 1)\n",
    "                    pre[y] = self.max(pre[y], y - x + 1)\n",
    "                    break\n",
    "                left += 1\n",
    "                right -= 1\n",
    "        # 由此还可以获得以某个位置开头或者结尾的最长回文子串\n",
    "        for i in range(1, n):\n",
    "            if i - pre[i - 1] - 1 >= 0 and s[i] == s[i - pre[i - 1] - 1]:\n",
    "                pre[i] = self.max(pre[i], pre[i - 1] + 2)\n",
    "\n",
    "        for i in range(n - 2, -1, -1):\n",
    "            pre[i] = self.max(pre[i], pre[i + 1] - 2)\n",
    "\n",
    "        for i in range(n - 2, -1, -1):\n",
    "            if i + post[i + 1] + 1 < n and s[i] == s[i + post[i + 1] + 1]:\n",
    "                post[i] = self.max(post[i], post[i + 1] + 2)\n",
    "        for i in range(1, n):\n",
    "            post[i] = self.max(post[i], post[i - 1] - 2)\n",
    "\n",
    "        return post, pre\n",
    "\n",
    "class Solution:\n",
    "    def maxProduct(self, s: str) -> int:\n",
    "        post, pre = ManacherPlindrome().palindrome_longest(s)\n",
    "  \n",
    "        n = len(s)\n",
    "        for i in range(n-2, -1, -1):\n",
    "            post[i] = post[i] if post[i] > post[i+1] and post[i] % 2 else post[i+1]\n",
    "        \n",
    "        ans = x = 0\n",
    "        for i in range(n-1):\n",
    "            x = pre[i] if x < pre[i] and pre[i] % 2 else x\n",
    "            if x * post[i+1] > ans:\n",
    "                ans = x*post[i+1]\n",
    "        return ans"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maxProduct(self, s: str) -> int:\n",
    "        \n",
    "        t = '#' + '#'.join(list(s)) + '#'\n",
    "        \n",
    "        def expand(a, i, j):\n",
    "            while i >= 0 and j < len(a) and a[i] == a[j]:\n",
    "                i -= 1\n",
    "                j += 1\n",
    "            return (j - i - 1) // 2\n",
    "        \n",
    "        right = mid = 0\n",
    "        z = [0] * len(t)\n",
    "        for i in range(len(t)):\n",
    "            cur_min_len = 0\n",
    "            if right > i:\n",
    "                cur_min_len = min(z[2*mid - i], right - i)\n",
    "            cur_min_len = expand(t, i - cur_min_len ,i + cur_min_len)\n",
    "            \n",
    "            if cur_min_len + i > right:\n",
    "                right = cur_min_len + i\n",
    "                mid = i\n",
    "            \n",
    "            z[i] = cur_min_len\n",
    "        \n",
    "        n = len(s)\n",
    "        left = [1] * n\n",
    "        st = deque()\n",
    "        for i in range(n):\n",
    "            cur = 1\n",
    "            while st and i >= st[0][1]:\n",
    "                cur = max(cur, z[2*st[0][0] + 1])\n",
    "                st.popleft()\n",
    "            if st:\n",
    "                cur = max(cur, (i - st[0][0]) * 2 + 1)\n",
    "            left[i] = max(left[i - 1], cur)\n",
    "            if z[2*i + 1] > 1:\n",
    "                st.append([i, i + (z[2*i + 1] // 2)])\n",
    "        #print(left)\n",
    "        st = deque()\n",
    "        pre = ans = 1\n",
    "        for i in range(n - 1, 0, -1):\n",
    "            cur = 1\n",
    "            while st and i <= st[0][1]:\n",
    "                cur = max(cur, z[2*st[0][0] + 1])\n",
    "                st.popleft()\n",
    "            if st:\n",
    "                cur = max(cur, (st[0][0] - i) * 2 + 1)\n",
    "            cur = max(pre, cur)\n",
    "            pre = cur\n",
    "            #print(i, cur)\n",
    "            ans = max(ans, cur * left[i - 1])\n",
    "            if z[2*i + 1] > 1:\n",
    "                st.append([i, i - (z[2*i + 1]) // 2])\n",
    "        return ans"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Manacher:\n",
    "    '''\n",
    "    马拉车算法O(n)\n",
    "    计算字符串的所有回文信息\n",
    "    https://oi-wiki.org/string/manacher/\n",
    "    '''\n",
    "    def __init__(self,s):\n",
    "        self.s = s\n",
    "        self.n = len(s)\n",
    "    \n",
    "    def get_odd(self):\n",
    "        '''\n",
    "        获取每个中心点的奇回文半径\n",
    "        '''\n",
    "        # Python Version\n",
    "        d1 = [0] * self.n\n",
    "        l, r = 0, -1\n",
    "        for i in range(0, self.n):\n",
    "            k = 1 if i > r else min(d1[l + r - i], r - i + 1)\n",
    "            while 0 <= i - k and i + k < self.n and self.s[i - k] == self.s[i + k]:\n",
    "                k += 1\n",
    "            d1[i] = k\n",
    "            k -= 1\n",
    "            if i + k > r:\n",
    "                l = i - k\n",
    "                r = i + k\n",
    "        return d1\n",
    "\n",
    "    def get_even(self):\n",
    "        '''\n",
    "        获取每个中心点的偶回文半径\n",
    "        '''\n",
    "        # Python Version\n",
    "        d2 = [0] * self.n\n",
    "        l, r = 0, -1\n",
    "        for i in range(0, self.n):\n",
    "            k = 0 if i > r else min(d2[l + r - i + 1], r - i + 1)\n",
    "            while 0 <= i - k - 1 and i + k < self.n and self.s[i - k - 1] == self.s[i + k]:\n",
    "                k += 1\n",
    "            d2[i] = k\n",
    "            k -= 1\n",
    "            if i + k > r:\n",
    "                l = i - k - 1\n",
    "                r = i + k\n",
    "        return d2\n",
    "\n",
    "class Solution:\n",
    "    def maxProduct(self, s: str) -> int:\n",
    "        n = len(s)\n",
    "        ma1 = Manacher(s)\n",
    "        d1 = ma1.get_odd()\n",
    "        pre = [0]*n #pre[i]: s[:i]中的最长奇回文半径\n",
    "        suf = [0]*n #odd[i]: s[i:]中的最长奇回文半径\n",
    "        premax = 1\n",
    "        sufmax = 1\n",
    "        dq1 = deque()\n",
    "        dq2 = deque()\n",
    "        for i in range(n-1):\n",
    "            j = n-i-1\n",
    "            dq1.append((i,d1[i]))\n",
    "            while dq1[0][0]+dq1[0][1]-1<i:\n",
    "                dq1.popleft()\n",
    "            premax = max(premax,i - dq1[0][0] + 1)\n",
    "            dq2.append((j,d1[j]))\n",
    "            while dq2[0][0]-dq2[0][1]+1>j:\n",
    "                dq2.popleft()\n",
    "            sufmax = max(sufmax,dq2[0][0] - j + 1)\n",
    "            pre[i+1] = premax\n",
    "            suf[j] = sufmax\n",
    "        ans = 0\n",
    "        #枚举分界点\n",
    "        for i in range(1,n):\n",
    "            m1 = pre[i]*2-1\n",
    "            m2 = suf[i]*2-1\n",
    "            ans = max(ans,m1*m2)\n",
    "        return ans\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "from collections import deque\n",
    "from typing import List\n",
    "\n",
    "class Manacher:\n",
    "    def __init__(self, s):\n",
    "        self.s = s\n",
    "        self.n = len(s)\n",
    "    \n",
    "    def get_odd(self):\n",
    "        d1 = [0] * self.n\n",
    "        l, r = 0, -1\n",
    "        for i in range(self.n):\n",
    "            k = 1 if i > r else min(d1[l + r - i], r - i + 1)\n",
    "            while 0 <= i - k and i + k < self.n and self.s[i - k] == self.s[i + k]:\n",
    "                k += 1\n",
    "            d1[i] = k\n",
    "            k -= 1\n",
    "            if i + k > r:\n",
    "                l = i - k\n",
    "                r = i + k\n",
    "        return d1\n",
    "\n",
    "class Solution:\n",
    "    def maxProduct(self, s: str) -> int:\n",
    "        n = len(s)\n",
    "        ma1 = Manacher(s)\n",
    "        d1 = ma1.get_odd()\n",
    "        \n",
    "        pre = [0] * n\n",
    "        suf = [0] * n\n",
    "        \n",
    "        premax = 1\n",
    "        sufmax = 1\n",
    "        dq1 = deque()\n",
    "        dq2 = deque()\n",
    "        \n",
    "        for i in range(n-1):\n",
    "            j = n - i - 1\n",
    "            \n",
    "            dq1.append((i, d1[i]))\n",
    "            while dq1 and dq1[0][0] + dq1[0][1] - 1 < i:\n",
    "                dq1.popleft()\n",
    "            premax = max(premax, i - dq1[0][0] + 1)\n",
    "            \n",
    "            dq2.append((j, d1[j]))\n",
    "            while dq2 and dq2[0][0] - dq2[0][1] + 1 > j:\n",
    "                dq2.popleft()\n",
    "            sufmax = max(sufmax, dq2[0][0] - j + 1)\n",
    "            \n",
    "            pre[i+1] = premax\n",
    "            suf[j] = sufmax\n",
    "        \n",
    "        ans = 0\n",
    "        for i in range(1, n):\n",
    "            m1 = pre[i] * 2 - 1\n",
    "            m2 = suf[i] * 2 - 1\n",
    "            ans = max(ans, m1 * m2)\n",
    "        \n",
    "        return ans\n",
    "\n",
    "# Test cases\n",
    "s1 = \"ababbb\"\n",
    "s2 = \"zaaaxbbby\"\n",
    "sol = Solution()\n",
    "print(sol.maxProduct(s1))  # Should output 9\n",
    "print(sol.maxProduct(s2))  # Should output 9\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maxProduct(self, nums: List[int]) -> int:\n",
    "        a,b=0,-1\n",
    "        for i in nums:\n",
    "            if i>a:\n",
    "                a,b=i,a\n",
    "            elif i>b:\n",
    "                a,b=a,i\n",
    "        return (a-1)*(b-1)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maxProduct(self, nums: List[int]) -> int:\n",
    "        num1_max = max(nums)\n",
    "        nums.remove(num1_max)\n",
    "        num2_max = max(nums)\n",
    "        return (num1_max - 1) * (num2_max - 1)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maxProduct(self, nums: List[int]) -> int:\n",
    "        def F_aux(n,dp,vis):\n",
    "            if vis[n]:\n",
    "                return dp[n]\n",
    "            else:\n",
    "                dp[n]=max(F_aux(n-1,dp,vis), (nums[n-1]-1)*(max(nums[:n-1])-1))\n",
    "                vis[n]=1\n",
    "                return dp[n]\n",
    "    \n",
    "        def F(n):\n",
    "            dp=[0 for i in range(n+1)]\n",
    "            vis=[0 for i in range(n+1)]\n",
    "            vis[2]=1\n",
    "            dp[2]=(nums[1]-1)*(nums[0]-1)\n",
    "            return F_aux(n,dp,vis)\n",
    "        \n",
    "        return F(len(nums))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maxProduct(self, nums: List[int]) -> int:\n",
    "        max1 = 0\n",
    "        max2 = -1\n",
    "        for i in nums:\n",
    "            if i>max1:\n",
    "                max2 = max1\n",
    "                max1 = i\n",
    "            elif i>max2:\n",
    "                max2 = i\n",
    "        return (max1-1)*(max2-1)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "from typing import List\n",
    "from random import randint\n",
    "\n",
    "\n",
    "class Solution:\n",
    "\n",
    "    def maxProduct(self, nums: List[int]) -> int:\n",
    "\n",
    "        def swap(i, j):\n",
    "            nums[i], nums[j] = nums[j], nums[i]\n",
    "\n",
    "        def gp(si, ei):\n",
    "            p = randint(si, ei)\n",
    "            swap(si, p)\n",
    "            mark = si\n",
    "            pivot = nums[si]\n",
    "            for i in range(si + 1, ei + 1):\n",
    "                if nums[i] < pivot:\n",
    "                    mark += 1\n",
    "                    swap(mark, i)\n",
    "            swap(mark, si)\n",
    "            return mark\n",
    "\n",
    "        target = len(nums) - 2\n",
    "\n",
    "        def dc(si, ei):\n",
    "            p = gp(si, ei)\n",
    "            if p < target:\n",
    "                return dc(p + 1, ei)\n",
    "            elif p > target:\n",
    "                return dc(si, p - 1)\n",
    "            else:\n",
    "                return p\n",
    "\n",
    "        idx = dc(0, len(nums) - 1)\n",
    "        return (nums[idx] - 1) * (nums[idx + 1] - 1)\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maxProduct(self, nums: List[int]) -> int:\n",
    "        max_1 = -float(\"inf\")\n",
    "        max_2 = -float(\"inf\")\n",
    "        for i in nums:\n",
    "            if i >= max_2:\n",
    "                max_1,max_2 = max_2,i\n",
    "            elif i>= max_1:\n",
    "                max_1 = i\n",
    "        return (max_1-1)*(max_2-1)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maxProduct(self, nums: List[int]) -> int:\n",
    "        max1 = nums[0] if nums[0] >= nums[1] else nums[1]\n",
    "        max2 = nums[0] if nums[0] < nums[1] else nums[1]\n",
    "        # if nums[0] >= nums[1]:\n",
    "        #     max1 = nums[0]\n",
    "        #     max2 = nums[1]\n",
    "        # else:\n",
    "        #     max1 = nums[1]\n",
    "        #     max2 = nums[0]\n",
    "        length = len(nums)\n",
    "        for i in range(2,length):\n",
    "            if nums[i] > max1:\n",
    "                max2 = max1\n",
    "                max1 = nums[i]\n",
    "            elif nums[i] > max2:\n",
    "                max2 = nums[i]\n",
    "        return (max1-1)*(max2-1)\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maxProduct(self, nums: List[int]) -> int:\n",
    "        nums.sort()\n",
    "        return (nums[-1] -1)*(nums[-2]-1)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maxProduct(self, nums: List[int]) -> int:\n",
    "        # 方式一\n",
    "        # nums.sort()\n",
    "        # return (nums[len(nums)-1]-1) * (nums[len(nums)-2]-1)\n",
    "\n",
    "        # 方式二\n",
    "        a = max(nums)\n",
    "        nums.remove(a)\n",
    "        b = max(nums)\n",
    "        return (a-1)*(b-1)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maxProduct(self, nums: List[int]) -> int:\n",
    "        nums.sort()\n",
    "        return max((nums[0] - 1) * (nums[1] - 1), (nums[-1] - 1) * (nums[-2] - 1))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maxProduct(self, nums: List[int]) -> int:\n",
    "        nums.sort()\n",
    "        return (nums[-1] - 1) * (nums[-2] - 1)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maxProduct(self, nums: List[int]) -> int:\n",
    "        nums.sort()\n",
    "        return (nums[-1] - 1) * (nums[-2] - 1)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maxProduct(self, nums: List[int]) -> int:\n",
    "        a = max(nums)\n",
    "        nums.remove(a)\n",
    "        b = max(nums)\n",
    "        return (a-1) * (b-1)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maxProduct(self, nums: List[int]) -> int:\n",
    "        nums_sorted = sorted(nums,reverse = True)\n",
    "        return (nums_sorted[0] - 1) * (nums_sorted[1] - 1)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maxProduct(self, nums: List[int]) -> int:\n",
    "        a = max(nums)\n",
    "        nums.remove(a)\n",
    "        b = max(nums)\n",
    "        return (a - 1) * (b - 1)\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maxProduct(self, nums: List[int]) -> int:\n",
    "        max1 = nums[0] if nums[0] >= nums[1] else nums[1]\n",
    "        max2 = nums[0] if nums[0] < nums[1] else nums[1]\n",
    "        # if nums[0] >= nums[1]:\n",
    "        #     max1 = nums[0]\n",
    "        #     max2 = nums[1]\n",
    "        # else:\n",
    "        #     max1 = nums[1]\n",
    "        #     max2 = nums[0]\n",
    "        length = len(nums)\n",
    "        for i in range(2,length):\n",
    "            if nums[i] > max1:\n",
    "                max2 = max1\n",
    "                max1 = nums[i]\n",
    "            elif nums[i] > max2:\n",
    "                max2 = nums[i]\n",
    "        return (max1-1)*(max2-1)\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maxProduct(self, nums: List[int]) -> int:\n",
    "        nums.sort()\n",
    "        return (nums[-1]-1) * (nums[-2]-1)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maxProduct(self, nums: List[int]) -> int:\n",
    "        a = max(nums)\n",
    "        nums.remove(a)\n",
    "        b = max(nums)\n",
    "        return (a - 1) * (b - 1)\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maxProduct(self, nums: List[int]) -> int:\n",
    "        nums.sort()\n",
    "        return (nums[-1] -1)*(nums[-2]-1)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maxProduct(self, nums: List[int]) -> int:\n",
    "        i = nums.pop(nums.index(max(nums)))\n",
    "        j = nums.pop(nums.index(max(nums)))\n",
    "        return (i-1)*(j-1)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maxProduct(self, nums: List[int]) -> int:\n",
    "        x = max(nums)\n",
    "        nums.remove(x)\n",
    "        y = max(nums)\n",
    "        ans = (x - 1) * (y - 1)\n",
    "        return ans"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maxProduct(self, nums: List[int]) -> int:\n",
    "        return (sorted(nums,reverse=False)[-1]-1) * (sorted(nums,reverse=False)[-2]-1)\n",
    "        "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maxProduct(self, nums: List[int]) -> int:\n",
    "        max1 = nums[0] if nums[0] >= nums[1] else nums[1]\n",
    "        max2 = nums[0] if nums[0] < nums[1] else nums[1]\n",
    "        # if nums[0] >= nums[1]:\n",
    "        #     max1 = nums[0]\n",
    "        #     max2 = nums[1]\n",
    "        # else:\n",
    "        #     max1 = nums[1]\n",
    "        #     max2 = nums[0]\n",
    "        length = len(nums)\n",
    "        for i in range(2,length):\n",
    "            if nums[i] > max1:\n",
    "                max2 = max1\n",
    "                max1 = nums[i]\n",
    "            elif nums[i] > max2:\n",
    "                max2 = nums[i]\n",
    "        return (max1-1)*(max2-1)\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maxProduct(self, nums: List[int]) -> int:\n",
    "        nums.sort()\n",
    "        return (nums[-1] - 1) *(nums[-2] -1)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maxProduct(self, nums: List[int]) -> int:\n",
    "        return (sorted(nums,reverse=False)[-1]-1) * (sorted(nums,reverse=False)[-2]-1)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maxProduct(self, nums: List[int]) -> int:\n",
    "        one = max(nums)\n",
    "        nums.pop(nums.index(one))\n",
    "        two = max(nums)\n",
    "        return (one-1)*(two-1)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maxProduct(self, nums: List[int]) -> int:\n",
    "        heap=[-nums[i] for i in range(len(nums))]\n",
    "        heapq.heapify(heap)\n",
    "        return (heapq.heappop(heap)+1)*(heapq.heappop(heap)+1)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maxProduct(self, nums: List[int]) -> int:\n",
    "        \"\"\"\n",
    "        To get the max value of ... is equals to get the largest and the second largest elements\n",
    "        \"\"\"\n",
    "        if not nums or len(nums) < 2:\n",
    "            return -1\n",
    "        \n",
    "        max_heap = [-n for n in nums]\n",
    "        heapq.heapify(max_heap)\n",
    "        return (heapq.heappop(max_heap) * -1 - 1) * (heapq.heappop(max_heap) * -1 - 1)\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maxProduct(self, nums: List[int]) -> int:\n",
    "        i = nums.pop(nums.index(max(nums)))\n",
    "        j = nums.pop(nums.index(max(nums)))\n",
    "        return (i-1)*(j-1)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maxProduct(self, nums: List[int]) -> int:\n",
    "        nums.sort(reverse=True)\n",
    "        return (nums[0]-1)*(nums[1]-1)\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maxProduct(self, nums: List[int]) -> int:\n",
    "        res = 0\n",
    "        for i in range(len(nums)):\n",
    "            for j in range(i+1,len(nums)):\n",
    "                if (nums[i]-1)*(nums[j]-1)>res:\n",
    "                    res = (nums[i]-1)*(nums[j]-1)\n",
    "        return res"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maxProduct(self, nums: List[int]) -> int:\n",
    "        li = sorted(nums,reverse=False)\n",
    "        return (li[-1]-1) * (li[-2]-1)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maxProduct(self, nums: List[int]) -> int:\n",
    "        nums.sort()\n",
    "        return (nums[-1] - 1) * (nums[-2] - 1) "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maxProduct(self, nums: List[int]) -> int:\n",
    "        nums.sort()\n",
    "        n = len(nums)\n",
    "        mark = (nums[n-1]-1)*(nums[n-2]-1)\n",
    "        return mark"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maxProduct(self, nums: List[int]) -> int:\n",
    "        max=0\n",
    "        for i in range(len(nums)-1):\n",
    "            for j in range(i+1,len(nums)):\n",
    "                if ((nums[i]-1)*(nums[j]-1))>=max:\n",
    "                    max=(nums[i]-1)*(nums[j]-1)\n",
    "        return max"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maxProduct(self, nums: List[int]) -> int:\n",
    "        nums.sort()\n",
    "        return (nums[-1]-1)*(nums[-2]-1)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maxProduct(self, nums: List[int]) -> int:\n",
    "        nums = sorted(nums, reverse = True)\n",
    "        return (nums[0] - 1) * (nums[1] - 1)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maxProduct(self, nums: List[int]) -> int:\n",
    "        fstmax = 0\n",
    "        secmax = 0\n",
    "        for i in nums:\n",
    "            if i > fstmax:\n",
    "                secmax = fstmax\n",
    "                fstmax = i\n",
    "            elif i > secmax:\n",
    "                secmax = i\n",
    "        return (fstmax-1) * (secmax-1)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maxProduct(self, nums: List[int]) -> int:\n",
    "        # 初始化最大值为0\n",
    "        max_product = 0\n",
    "\n",
    "        # 遍历数组\n",
    "        for i in range(len(nums)):\n",
    "            for j in range(i+1, len(nums)):\n",
    "                # 计算当前下标对应的乘积\n",
    "                product = (nums[i] - 1) * (nums[j] - 1)\n",
    "\n",
    "                # 更新最大值\n",
    "                max_product = max(max_product, product)\n",
    "\n",
    "        return max_product"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maxProduct(self, nums: List[int]) -> int:\n",
    "        nums = sorted(nums, reverse=True)\n",
    "        return (nums[0]-1)*(nums[1] - 1)\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maxProduct(self, nums: List[int]) -> int:\n",
    "       \n",
    "        nums.sort()\n",
    "        return (nums[-1] - 1) * (nums[-2] - 1)\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maxProduct(self, nums: List[int]) -> int:\n",
    "        li = sorted(nums,reverse=False)\n",
    "        a = li[-1]-1\n",
    "        b = li[-2]-1\n",
    "        return a * b"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maxProduct(self, nums: List[int]) -> int:\n",
    "        x = y = 1\n",
    "        for n in nums:\n",
    "            if n > x: y, x = x, n\n",
    "            elif n > y: y = n\n",
    "        return (x - 1) * (y - 1)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maxProduct(self, nums: List[int]) -> int:\n",
    "        n = len(nums)\n",
    "        mul = float(\"-inf\")\n",
    "        for i in range(n):\n",
    "            for j in range(i+1, n):\n",
    "                if (nums[i]-1)*(nums[j]-1) > mul:\n",
    "                    mul = (nums[i]-1)*(nums[j]-1) \n",
    "        return mul"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maxProduct(self, nums: List[int]) -> int:\n",
    "        a, b = nums[0], nums[1]\n",
    "        if a < b:\n",
    "            a, b = b, a\n",
    "        for i in range(2, len(nums)):\n",
    "            num = nums[i]\n",
    "            if num > a:\n",
    "                a, b = num, a\n",
    "            elif num > b:\n",
    "                b = num\n",
    "        return (a-1)*(b-1)\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maxProduct(self, nums: List[int]) -> int:\n",
    "        nums.sort()\n",
    "        return (nums[-2]-1) * (nums[-1]-1)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maxProduct(self, nums: List[int]) -> int:\n",
    "        return (sorted(nums, reverse=True)[1]-1) * (sorted(nums, reverse=True)[0]-1)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maxProduct(self, nums: List[int]) -> int:\n",
    "        nums.sort()\n",
    "        return (nums[-1] - 1) * (nums[-2] - 1)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maxProduct(self, nums: List[int]) -> int:\n",
    "        mx1, mx2 = max(nums[0], nums[1]), min(nums[0], nums[1])\n",
    "        for i in range(2, len(nums)):\n",
    "            tmp = nums[i]\n",
    "            if tmp > mx1:\n",
    "                mx1, mx2 = tmp, mx1\n",
    "                continue\n",
    "            if tmp > mx2 and tmp <= mx1:\n",
    "                mx2 = tmp\n",
    "        return (mx1 - 1) * (mx2 - 1)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maxProduct(self, nums: List[int]) -> int:\n",
    "        nums.sort()\n",
    "        return (nums[-1]-1)*(nums[-2]-1)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maxProduct(self, nums: List[int]) -> int:\n",
    "        i = nums.pop(nums.index(max(nums)))\n",
    "        j = nums.pop(nums.index(max(nums)))\n",
    "        return (i-1)*(j-1)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maxProduct(self, nums: List[int]) -> int:\n",
    "        return (sorted(nums,reverse=False)[-1]-1) * (sorted(nums,reverse=False)[-2]-1)\n",
    "        "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maxProduct(self, nums: List[int]) -> int:\n",
    "        nums.sort()\n",
    "        return (nums[-1]-1)*(nums[-2]-1)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\r\n",
    "    def maxProduct(self, nums: List[int]) -> int:\r\n",
    "        nums.sort()\r\n",
    "        return (nums[-1]-1)*(nums[-2]-1)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maxProduct(self, nums: List[int]) -> int:\n",
    "        nums.sort()\n",
    "        return (nums[-1]-1)*(nums[-2]-1)\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maxProduct(self, nums: List[int]) -> int:\n",
    "        \"\"\"\n",
    "        To get the max value of ... is equals to get the largest and the second largest elements\n",
    "        \"\"\"\n",
    "        if not nums or len(nums) < 2:\n",
    "            return 0\n",
    "        elif len(nums) == 2:\n",
    "            return (nums[0] - 1) * (nums[1] - 1)\n",
    "        else:\n",
    "            sorted_nums = sorted(nums)\n",
    "            largest, second_largest = sorted_nums[-1], sorted_nums[-2]\n",
    "            return (largest - 1) * (second_largest - 1)\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maxProduct(self, nums: List[int]) -> int:\n",
    "        nums.sort(reverse=True)\n",
    "        return (nums[0]-1)*(nums[1]-1)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maxProduct(self, nums: List[int]) -> int:\n",
    "        a, b = nums[0], nums[1]\n",
    "        if a < b:\n",
    "            a, b = b, a\n",
    "        for i in range(2, len(nums)):\n",
    "            num = nums[i]\n",
    "            if num > a:\n",
    "                a, b = num, a\n",
    "            elif num > b:\n",
    "                b = num\n",
    "        return (a-1)*(b-1)\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maxProduct(self, nums: List[int]) -> int:\n",
    "        a, b = nums[0], nums[1]\n",
    "        if a < b:\n",
    "            a, b = b, a\n",
    "        for i in range(2, len(nums)):\n",
    "            num = nums[i]\n",
    "            if num > a:\n",
    "                a, b = num, a\n",
    "            elif num > b:\n",
    "                b = num\n",
    "        return (a-1)*(b-1)\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maxProduct(self, nums: List[int]) -> int:\n",
    "        max1 = max(nums[0:2])\n",
    "        max2 = min(nums[0:2])\n",
    "        for i in range(2,len(nums)):\n",
    "            print(max1,max2)\n",
    "            if nums[i] >= max1:\n",
    "                max2 = max1\n",
    "                max1 = nums[i]\n",
    "            elif nums[i] > max2:\n",
    "                max2 = nums[i]\n",
    "                \n",
    "        return (max1-1) * (max2-1)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maxProduct(self, nums: List[int]) -> int:\n",
    "        nums.sort(reverse=True)\n",
    "        return (nums[0]-1)*(nums[1]-1)\n",
    "\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maxProduct(self, nums: List[int]) -> int:\n",
    "        nums.sort()\n",
    "        length = len(nums)\n",
    "        return (nums[length - 1] - 1) * (nums[length - 2] - 1)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maxProduct(self, nums: List[int]) -> int:\n",
    "        mx1, mx2 = max(nums[0], nums[1]), min(nums[0], nums[1])\n",
    "        for i in range(2, len(nums)):\n",
    "            tmp = nums[i]\n",
    "            if tmp > mx1:\n",
    "                mx1, mx2 = tmp, mx1\n",
    "                continue\n",
    "            if tmp > mx2 and tmp <= mx1:\n",
    "                mx2 = tmp\n",
    "        return (mx1 - 1) * (mx2 - 1)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maxProduct(self, nums: List[int]) -> int:\n",
    "        nums.sort(reverse=True)\n",
    "        return (nums[0]-1)*(nums[1]-1)\n",
    "\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maxProduct(self, nums: List[int]) -> int:\n",
    "        a = max(nums)\n",
    "        nums.remove(a)\n",
    "        b = max(nums)\n",
    "        return (a - 1) * (b - 1)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maxProduct(self, nums: List[int]) -> int:\n",
    "        nums.sort()\n",
    "        a = (nums[0]-1)*(nums[1]-1)\n",
    "        b = (nums[-1]-1)*(nums[-2]-1)\n",
    "        return max(a, b)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maxProduct(self, nums: List[int]) -> int:\n",
    "        n = len(nums)\n",
    "        res = 0\n",
    "        for i in range(n-1):\n",
    "            for j in range(i+1,n):\n",
    "                a = (nums[i]-1) * (nums[j]-1)\n",
    "                res = max(res,a)\n",
    "        return res"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maxProduct(self, nums: List[int]) -> int:\n",
    "        a,b=0,0\n",
    "        for i in nums:\n",
    "            if i>a:\n",
    "                if a>b:b=a\n",
    "                a=i\n",
    "            elif i>b:b=i\n",
    "        return (a-1)*(b-1)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maxProduct(self, words: List[str]) -> int:\n",
    "        def f(x):\n",
    "            ret=0\n",
    "            for i in x:\n",
    "                ret|=(1<<(ord(i)-ord('a')))\n",
    "            return [ret,len(x)]\n",
    "        ws=[f(x) for x in words]\n",
    "        ret=0\n",
    "        for i in range(len(ws)):\n",
    "            for j in range(i+1,len(ws)):\n",
    "                if ws[i][0]&ws[j][0]==0:\n",
    "                    ret=max(ret,ws[i][1]*ws[j][1])\n",
    "        return ret\n",
    "        "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "from collections import defaultdict\n",
    "\n",
    "class Solution:\n",
    "    def maxProduct(self, words: List[str]) -> int:\n",
    "        def hepler(s:str):\n",
    "            res = 0 \n",
    "            for i in s:\n",
    "                res |= 1<<(ord(i)-97)\n",
    "            return res\n",
    "\n",
    "        cache = defaultdict(lambda :0)\n",
    "        for i in words:\n",
    "            digit = hepler(i)\n",
    "            if cache[digit] < len(i):\n",
    "                cache[digit] = len(i)\n",
    "\n",
    "        k = list(cache.keys())\n",
    "        n = len(k)\n",
    "        res = 0\n",
    "        for i in range(n):\n",
    "            for j in range(i+1, n):\n",
    "                if (k[i] & k[j]) == 0:\n",
    "                    res = max(res, cache[k[i]]*cache[k[j]])\n",
    "        return res\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maxProduct(self, words: List[str]) -> int:\n",
    "        counter = []\n",
    "        wordsLength = []\n",
    "        for word in words:\n",
    "            tmp = [0]*26\n",
    "            length = 0\n",
    "            for char in word:\n",
    "                tmp[ord(char)-ord(\"a\")] = 1\n",
    "                length += 1\n",
    "            counter.append(tmp)\n",
    "            wordsLength.append(length)\n",
    "        res = 0\n",
    "        for i in range(len(words)):\n",
    "            for j in range(i+1, len(words)):\n",
    "                if not self.hasCommonChar(i, j, counter):\n",
    "                    res = max(res, wordsLength[i]*wordsLength[j])\n",
    "        return res\n",
    "        \n",
    "    def hasCommonChar(self, i, j, counter):\n",
    "        for m in range(26):\n",
    "            if counter[i][m] == 1 and counter[j][m] == 1:\n",
    "                return True\n",
    "        return False"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maxProduct(self, words: List[str]) -> int:\n",
    "        # 先生成masks数组\n",
    "        masks = {}\n",
    "        for word in words:\n",
    "            xor = 0\n",
    "            for w in word:\n",
    "                xor |= 1 << (ord(w) - ord('a'))\n",
    "            if xor in masks.keys():\n",
    "                masks[xor] = max(masks[xor], len(word))\n",
    "            else:\n",
    "                masks[xor] = len(word)\n",
    "        m = 0\n",
    "        for k, v in masks.items():\n",
    "            for p, d in masks.items():\n",
    "                if k & p == 0 and v*d>m:\n",
    "                    m = v*d\n",
    "        return m\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maxProduct(self, words: List[str]) -> int:\n",
    "        def hashset(word):\n",
    "            return sum(1 << (ord(c) - ord('a')) for c in set(word))\n",
    "\n",
    "        d, ans = defaultdict(int), 0\n",
    "        for w in words:\n",
    "            h = hashset(w)\n",
    "            if d[h] < len(w):\n",
    "                #可能有包含字母相同但更长的单词\n",
    "                for other in d:\n",
    "                    if not other & h:\n",
    "                        ans = max(d[other] * len(w), ans)\n",
    "                d[h] = len(w)\n",
    "\n",
    "        return ans\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maxProduct(self, words: List[str]) -> int:\n",
    "        masks = [reduce(lambda a, b: a | (1 << (ord(b) - ord('a'))), word, 0) for word in words]\n",
    "        return max((len(x[1]) * len(y[1]) for x, y in product(zip(masks, words), repeat=2) if x[0] & y[0] == 0), default=0)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "\n",
    "class Solution:\n",
    "    def get_int(self, word: str) -> int:\n",
    "        ret = 0\n",
    "        for c in word:\n",
    "            ret |= 1 << (ord(c) - ord('a'))\n",
    "        return ret\n",
    "\n",
    "    def maxProduct(self, words: List[str]) -> int:\n",
    "        cache: Dict[int, int] = {}\n",
    "        for word in words:\n",
    "            i = self.get_int(word)\n",
    "            cache.setdefault(i, 0)\n",
    "            cache[i] = max(cache[i], len(word))\n",
    "        \n",
    "        ret = 0\n",
    "        \n",
    "        for key1 in cache:\n",
    "            for key2 in cache:\n",
    "                if key1 & key2 == 0:\n",
    "                    ret = max(ret, cache[key1] * cache[key2])\n",
    "        \n",
    "        return ret\n",
    "    "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maxProduct(self, words: List[str]) -> int:\n",
    "        masks = [reduce(lambda a, b: a | (1 << (ord(b) - ord('a'))), word, 0) for word in words]\n",
    "        return max((len(x[1]) * len(y[1]) for x, y in product(zip(masks, words), repeat=2) if x[0] & y[0] == 0), default=0)\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maxProduct(self, words: List[str]) -> int:\n",
    "        masks = [reduce(lambda a, b: a | (1 << (ord(b) - ord('a'))), word, 0) for word in words]\n",
    "        return max((len(x[1]) * len(y[1]) for x, y in product(zip(masks, words), repeat=2) if x  [0] & y[0] == 0), default=0)\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maxProduct(self, words: List[str]) -> int:\n",
    "        masks = [reduce(lambda a, b: a | (1 << (ord(b) - ord('a'))), word, 0) for word in words]\n",
    "        print(product(zip(masks, words), repeat=2))\n",
    "        return max((len(x[1]) * len(y[1]) for x, y in product(zip(masks, words), repeat=2) if x[0] & y[0] == 0), default=0)\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maxProduct(self, words: List[str]) -> int:\n",
    "        if not words:\n",
    "            return 0\n",
    "        n = len(words)\n",
    "        helper = [0]*n\n",
    "        for i in range(n):\n",
    "            b = 0\n",
    "            for j in words[i]:\n",
    "                helper[i] |= 1 << (ord(j) - 97)\n",
    "        return max([len(words[i]) * len(words[j]) for i in range(len(words)) for j in range(i, len(words)) if\n",
    "                   not helper[i] & helper[j]] or [0])\n",
    "\n",
    "\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maxProduct(self, words: List[str]) -> int:\n",
    "        max_val = 0\n",
    "        words_set = [set(word) for word in words]\n",
    "\n",
    "        for i in range(len(words) - 1):\n",
    "            for j in range(i + 1, len(words)):\n",
    "                if not (words_set[i] & words_set[j]):\n",
    "                    max_val = max(max_val, len(words[i]) * len(words[j]))\n",
    "        return max_val\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maxProduct(self, words: List[str]) -> int:\n",
    "        ## {l:[word ..]\n",
    "        ##  {}\n",
    "        l_word= defaultdict(list)\n",
    "        for word in words:\n",
    "            l_word[len(word)].append(set(word))\n",
    "        l_list  = sorted(l_word.keys(),reverse = True)\n",
    "        ans = 0 \n",
    "        for i in range(len(l_list)):\n",
    "            for j in range(i,len(l_list)):\n",
    "                if self.check(l_word[l_list[i]],l_word[l_list[j]]):\n",
    "                    ans = max(ans,l_list[i]*l_list[j])\n",
    "                    break\n",
    "        return ans\n",
    "\n",
    "    def check(self,word_list1,word_list2):\n",
    "        for word1 in word_list1:\n",
    "            for word2 in word_list2:\n",
    "                if len(word1.intersection(word2))==0:\n",
    "                    return True     \n",
    "        return False\n",
    "\n",
    "\n",
    "\n",
    "\n",
    "    "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maxProduct(self, words: List[str]) -> int:\n",
    "        masks = [reduce(lambda a, b: a | (1 << (ord(b) - ord('a'))), word, 0) for word in words]\n",
    "        return max((len(x[1]) * len(y[1]) for x, y in product(zip(masks, words), repeat=2) if x[0] & y[0] == 0), default=0)\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maxProduct(self, words: List[str]) -> int:\n",
    "        cset=[set(w) for w in words]\n",
    "        ans=0\n",
    "        for i,w in enumerate(words):\n",
    "            for j in range(i+1,len(words)):\n",
    "                if not cset[i]&cset[j]:\n",
    "                    ans=max(ans,len(w)*len(words[j]))\n",
    "        return ans\n",
    "        "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maxProduct(self, words: List[str]) -> int:\n",
    "        n=len(words)\n",
    "        cnt=[set(word) for word in words]\n",
    "        max_num=0\n",
    "        for i in range(n):\n",
    "            for j in range(i+1,n):\n",
    "                if not cnt[i]&cnt[j]:\n",
    "                    max_num=max(max_num,len(words[i])*len(words[j]))\n",
    "\n",
    "        return max_num\n",
    "\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maxProduct(self, words: List[str]) -> int:\n",
    "        cset=[set(w) for w in words]\n",
    "        ans=0\n",
    "        for i,w in enumerate(words):\n",
    "            for j in range(i+1,len(words)):\n",
    "                if not cset[i]&cset[j]:\n",
    "                    ans=max(ans,len(w)*len(words[j]))\n",
    "        return ans"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maxProduct(self, words: List[str]) -> int:\n",
    "        cset=[set(w) for w in words]\n",
    "        n=len(words)\n",
    "        maxlen=0\n",
    "        for i in range(n):\n",
    "            for j in range(i+1,n):\n",
    "                if not cset[i]&cset[j]:\n",
    "                    maxlen=max(maxlen, len(words[i])*len(words[j]))\n",
    "        return maxlen"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maxProduct(self, words: List[str]) -> int:\n",
    "        s = list()\n",
    "        for i in range(len(words)):\n",
    "            s.append(set(list(words[i])))\n",
    "        ans = 0\n",
    "        for i in range(len(words)):\n",
    "            for j in range(i + 1, len(words)):\n",
    "                if not s[i] & s[j]:\n",
    "                    ans = max(ans, len(words[i] * len(words[j])))\n",
    "        return ans"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maxProduct(self, words: List[str]) -> int:\n",
    "        max_val = 0\n",
    "        words_set = [set(word) for word in words]\n",
    "\n",
    "        for i in range(len(words) - 1):\n",
    "            for j in range(i + 1, len(words)):\n",
    "                if not (words_set[i] & words_set[j]):\n",
    "                    max_val = max(max_val, len(words[i]) * len(words[j]))\n",
    "        return max_val\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maxProduct(self, words: List[str]) -> int:\n",
    "        li = []\n",
    "        for i in words:\n",
    "            li.append(set(i))\n",
    "        ans = 0\n",
    "        for i in range(len(li) - 1):\n",
    "            for j in range(i + 1, len(li)):\n",
    "                if not li[i] & li[j]:\n",
    "                    ans = max(ans, len(words[i]) * len(words[j]))\n",
    "        return ans"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maxProduct(self, words: List[str]) -> int:\n",
    "        n = len(words)\n",
    "        ans = 0\n",
    "        word_list = [\"-\"] * n\n",
    "        for i in range(n):\n",
    "            word_list[i] = set(words[i])\n",
    "        for j in range(n):\n",
    "            for k in range(j+1, n):\n",
    "                if len(word_list[j]) + len(word_list[k]) <= 26 and not word_list[j] & word_list[k]:\n",
    "                    ans = max(ans, len(words[j]) * len(words[k]))\n",
    "        return ans"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maxProduct(self, words: List[str]) -> int:\n",
    "        new_words = [set(w) for w in words]\n",
    "        res = 0\n",
    "        for i in range(len(words)):\n",
    "            for j in range(i + 1, len(words)):\n",
    "                if not new_words[i] & new_words[j]:\n",
    "                    res = max(res, len(words[i]) * len(words[j]))\n",
    "        return res\n",
    "        # max_num = 0\n",
    "        # for i in range(len(words)):\n",
    "        #     for j in range(i+1,len(words)):\n",
    "        #         length_i = len(words[i])\n",
    "        #         length_j = len(words[j])\n",
    "        #         cnt = 0\n",
    "        #         words_i = \"\".join(list(set((words[i]))))\n",
    "        #         words_j = \"\".join(list(set((words[j]))))\n",
    "        #         if len(words_i) <= len(words_j):\n",
    "        #             for letter in words_i:\n",
    "        #                 if letter in words_j:\n",
    "        #                     cnt = 1\n",
    "        #                     break\n",
    "        #             if cnt == 0:\n",
    "        #                 num = length_i*length_j\n",
    "        #                 if num > max_num:\n",
    "        #                     # print(words[i],words[j])\n",
    "        #                     max_num = num\n",
    "        #         else:\n",
    "        #             for letter in words_j:\n",
    "        #                 if letter in words_i:\n",
    "        #                     cnt = 1\n",
    "        #                     break\n",
    "        #             if cnt == 0:\n",
    "        #                 num = length_i*length_j\n",
    "        #                 if num > max_num:\n",
    "        #                     # print(words[i],words[j])\n",
    "        #                     max_num = num\n",
    "        # return max_num"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maxProduct(self, words: List[str]) -> int:\n",
    "        def get_bit(word):\n",
    "            bit = 0\n",
    "            for i in word:\n",
    "                bit |= 1 << (ord(i) - ord(\"a\"))\n",
    "            return bit\n",
    "        res = 0\n",
    "        bit = [0] * len(words)\n",
    "        for i, j in enumerate(words):\n",
    "            bit[i] = get_bit(j)\n",
    "            # 优化了获得位和枚举元素的速度 向前遍历\n",
    "            for k, s in enumerate(words[:i]):\n",
    "                if (bit[k] & bit[i]) == 0:\n",
    "                    res = max(res, len(j)*len(s))\n",
    "        return res\n",
    "\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maxProduct(self, words: List[str]) -> int:\n",
    "        def common(s1,s2):\n",
    "            s = set(s1)\n",
    "            for i in s:\n",
    "                if i in s2:\n",
    "                    return False\n",
    "            return True\n",
    "\n",
    "        res = 0\n",
    "        for i in range(len(words)-1):\n",
    "            for j in range(i+1, len(words)):\n",
    "                if common(words[i],words[j]):\n",
    "                    res = max(res, len(words[i]) * len(words[j]))\n",
    "        return res\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maxProduct(self, words: list) -> int:\n",
    "        lenWords = len(words)\n",
    "        resNum = 0\n",
    "        for i in range(lenWords):\n",
    "            tempi = set(words[i])\n",
    "            for j in range(i+1,lenWords):\n",
    "                tempj = set(words[j])\n",
    "                if len(tempj&tempi)==0:\n",
    "                    templen = len(words[i])*len(words[j])\n",
    "                    resNum = templen if templen>resNum else resNum\n",
    "        return resNum"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maxProduct(self, words):\n",
    "        res=0\n",
    "        mask=[0]*len(words)\n",
    "        for i in range(len(words)):\n",
    "            for w in words[i]:\n",
    "                mask[i]|=1<<(ord(w)-ord('a'))\n",
    "        for i in range(len(words)):\n",
    "            for j in range(i+1,len(words)):\n",
    "                if mask[i]&mask[j]==0:\n",
    "                    res=max(res,len(words[i])*len(words[j]))\n",
    "        return res"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maxProduct(self, words: list[str]) -> int:\n",
    "        masks = collections.defaultdict(int)\n",
    "        for word in words:\n",
    "            mask = functools.reduce(\n",
    "                lambda a, b: a | (1 << (ord(b) - ord('a'))), word, 0\n",
    "            )\n",
    "            masks[mask] = max(masks[mask], len(word))\n",
    "        return max(\n",
    "            (\n",
    "                masks[x] * masks[y]\n",
    "                for x, y in itertools.product(masks, repeat=2)\n",
    "                if x & y == 0\n",
    "            ),\n",
    "            default=0,\n",
    "        )\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maxProduct(self, words: List[str]) -> int:\n",
    "        masks = defaultdict(int)\n",
    "        for word in words:\n",
    "            mask = reduce(lambda a, b: a | (1 << (ord(b) - ord('a'))), word, 0)\n",
    "            masks[mask] = max(masks[mask], len(word))\n",
    "        return max((masks[x] * masks[y] for x, y in product(masks, repeat=2) if x & y == 0), default=0)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maxProduct(self, words: List[str]) -> int:\n",
    "        def if_intersection(s1, s2):\n",
    "            return True if set(s1).intersection(set(s2)) else False\n",
    "        words = list(set(words))\n",
    "        res = []\n",
    "        n = len(words)\n",
    "        for i in range(n):\n",
    "            for j in range(i, n):\n",
    "                if not if_intersection(words[i], words[j]):\n",
    "                    res.append(len(words[i]) * len(words[j]))\n",
    "        return max(res) if res else 0\n",
    "\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maxProduct(self, words: List[str]) -> int:\n",
    "        words = list(set(words))\n",
    "        res = 0\n",
    "        for i in range(len(words)):\n",
    "            str1 = words[i]\n",
    "            l1 = len(str1)\n",
    "            for j in range(i+1,len(words)):\n",
    "                str2 = words[j]\n",
    "                l2 = len(str2)\n",
    "                num = 0\n",
    "                have = 0\n",
    "                while num < l2:\n",
    "                    if str2[num] in str1:\n",
    "                        have = 1\n",
    "                        break\n",
    "                    else:\n",
    "                        num += 1\n",
    "\n",
    "                if have == 0:\n",
    "                    res = max(res,l1*l2)\n",
    "\n",
    "        return res"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maxProduct(self, words: List[str]) -> int:\n",
    "        dic = {}\n",
    "        for word in words:\n",
    "            w2i = 0\n",
    "            for c in word:\n",
    "                w2i |= 1 << (ord(c) - ord('a'))\n",
    "            if w2i in dic:\n",
    "                if len(word) > dic[w2i]:\n",
    "                    dic[w2i] = len(word)\n",
    "            else:\n",
    "                dic[w2i] = len(word)\n",
    "        ans = 0\n",
    "        for k1, v1 in dic.items():\n",
    "            for k2, v2 in dic.items():\n",
    "                if k1 & k2 == 0:\n",
    "                    ans = max(ans, v1 * v2)\n",
    "        return ans"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maxProduct(self, words: List[str]) -> int:\n",
    "        res = 0\n",
    "        words = set(words)\n",
    "        words = list(words)\n",
    "        for i in range(len(words) - 1):\n",
    "            for j in range(i + 1, len(words)):\n",
    "                flag = True\n",
    "                for k in words[i]:\n",
    "                    if k in words[j]:\n",
    "                        flag = False\n",
    "                        break\n",
    "                if flag:\n",
    "                    res = max(res, len(words[i]) * len(words[j]))\n",
    "        return res"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maxProduct(self, words: List[str]) -> int:\n",
    "        ret = 0\n",
    "        bitWords = [0 for _ in words]\n",
    "        wordLengths = [0 for _ in words]\n",
    "        for i in range(len(words)):\n",
    "            for w in bytearray(words[i], 'ascii'):\n",
    "                bitWords[i] |= (1 << (w - 97))\n",
    "            wordLengths[i] = len(words[0])\n",
    "        for i in range(len(words)):\n",
    "            for j in range(i, len(words)):\n",
    "                if (bitWords[i] & bitWords[j]) == 0:\n",
    "                    ret = max(ret, len(words[i]) * len(words[j]))\n",
    "        return ret"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maxProduct(self, words: List[str]) -> int:\n",
    "        mask = [0] * len(words)\n",
    "        ans = 0\n",
    "        for i, s in enumerate(words):\n",
    "            for c in s:\n",
    "                mask[i] |= 1 << (ord(c) - ord(\"a\"))\n",
    "            for j, t in enumerate(words[:i]):\n",
    "                if (mask[i] & mask[j]) == 0:\n",
    "                    ans = max(ans, len(s) * len(t))\n",
    "        return ans"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maxProduct(self, words: List[str]) -> int:\n",
    "        res, mask = 0, [0 for i in words]\n",
    "        for i,j in enumerate(words):\n",
    "            for n in j:\n",
    "                mask[i] |= 1 << (ord(n) - ord('a')) \n",
    "        for i in range(len(words)):\n",
    "            for j in range(len(words)):\n",
    "                if (mask[i] & mask[j]) == 0:\n",
    "                    res = max(res, len(words[i])*len(words[j]))\n",
    "        return res"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maxProduct(self, words: List[str]) -> int:\n",
    "        import heapq\n",
    "        def is_overlap(str1, str2):\n",
    "            for c1 in str1:\n",
    "                if c1 in str2:\n",
    "                    return True\n",
    "            return False\n",
    "\n",
    "        res = 0\n",
    "        n = len(words)\n",
    "        for i in range(n):\n",
    "            for j in range(i+1, n):\n",
    "                if not is_overlap(words[i], words[j]):\n",
    "                    res = max(res, len(words[i]) * len(words[j]))\n",
    "        return res\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "  def maxProduct(self, words):\n",
    "    lw = []\n",
    "    for w in words:\n",
    "      u = 0\n",
    "      for c in w:\n",
    "        u |= 1<<(ord(c)-97)\n",
    "      if u == 0x3ffffff:\n",
    "        continue\n",
    "      lw.append((len(w), u))\n",
    "    res, n = 0, len(lw)\n",
    "    for i, (a, u) in enumerate(lw):\n",
    "      for b, v in islice(lw, i+1, n):\n",
    "        if u&v:\n",
    "          continue\n",
    "        if a*b > res:\n",
    "          res = a*b\n",
    "    return res"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maxProduct(self, words: List[str]) -> int:\n",
    "        def calculateBitmask(str):\n",
    "            bitmask = 0\n",
    "            for char in str:\n",
    "                bitmask |= 1<<(ord(char)-ord('a'))\n",
    "            return bitmask\n",
    "        \n",
    "        bitmasks = [calculateBitmask(str) for str in words]\n",
    "        maxLen = 0\n",
    "        for idx1 in range(len(words)):\n",
    "            for idx2 in range(idx1+1, len(words)):\n",
    "                if bitmasks[idx1]&bitmasks[idx2]==0:\n",
    "                    maxLen = max(maxLen, (len(words[idx1]))*(len(words[idx2])))\n",
    "        return maxLen\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "\n",
    "class Solution:\n",
    "    def maxProduct(self, words: List[str]) -> int:\n",
    "        max_value = 0\n",
    "        words = set(words)\n",
    "        words = list(words)\n",
    "        for i in range(len(words)-1):\n",
    "            for j in range(i+1, len(words)):\n",
    "                is_true = True\n",
    "                for k in words[i]:\n",
    "                    if k in words[j]:\n",
    "                        is_true = False\n",
    "                        break\n",
    "                if is_true:\n",
    "                    max_value = max(max_value, len(words[i]) * len(words[j]))\n",
    "                \n",
    "        return max_value"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maxProduct(self, words) -> int:\n",
    "        word_to_num = [0]*len(words)\n",
    "        for i in range(len(words)):\n",
    "            for ch in words[i]:\n",
    "                word_to_num[i] |= 1<<(ord(ch)-ord('a'))\n",
    "        mx = 0\n",
    "        for i in range(len(words)):\n",
    "            for j in range(i+1,len(words)):\n",
    "                if not (word_to_num[i] & word_to_num[j]):\n",
    "                    mx = max(mx,len(words[i])*len(words[j]))\n",
    "        return mx"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maxProduct(self, words: List[str]) -> int:\n",
    "        code = [0] * len(words)\n",
    "        ans:int = 0\n",
    "        # 计算第0个字符串对应的二进制码\n",
    "        for c in words[0]:\n",
    "            code[0] |= 1<<(ord(c)-ord('a'))\n",
    "        for i in range(1,len(words)):\n",
    "            for c in words[i]:\n",
    "                code[i] |= 1<<(ord(c)-ord('a'))#计算第i个字符串对应二进制码\n",
    "            for j in range(0,i):\n",
    "                if (not (code[j] & code[i])): \n",
    "                    ans = max(ans,len(words[i])*len(words[j]))\n",
    "        return ans\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maxProduct(self, words: List[str]) -> int:\n",
    "        mask = [0] * len(words)\n",
    "        ans = 0\n",
    "        for i, s in enumerate(words):\n",
    "            for c in s:\n",
    "                mask[i] |= 1<<(ord(c) - ord(\"a\"))\n",
    "            for j, t in enumerate(words[:i]):\n",
    "                if (mask[i] & mask[j]) == 0:\n",
    "                    ans = max(ans, len(s) * len(t))\n",
    "        return ans"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maxProduct(self, words: List[str]) -> int:\n",
    "        \"\"\"\n",
    "        mid = {}\n",
    "\n",
    "        count = 0\n",
    "        n = len(words)\n",
    "        for i in range(n):\n",
    "            for j in range(i+1,n):\n",
    "                flag = False\n",
    "                for item in words[i]:\n",
    "                    if item in words[j]:\n",
    "                        flag = True\n",
    "                        break\n",
    "                if not flag:\n",
    "                    val = len(words[i]) * len(words[j])\n",
    "                    if count < val:\n",
    "                        count = val\n",
    "        return count\n",
    "        \"\"\"\n",
    "        ###位运算的确省时间\n",
    "        mask = [0] * len(words)\n",
    "        ans = 0\n",
    "        for i, s in enumerate(words):\n",
    "            for c in s:\n",
    "                mask[i] |= 1 << (ord(c) - ord(\"a\"))\n",
    "            for j, t in enumerate(words[:i]):\n",
    "                if (mask[i] & mask[j]) == 0:\n",
    "                    ans = max(ans, len(s) * len(t))\n",
    "        return ans"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maxProduct(self, words: List[str]) -> int:\n",
    "        mask = [0] * len(words)\n",
    "        ans = 0\n",
    "        for i, s in enumerate(words):\n",
    "            for c in s:\n",
    "                mask[i] |= 1 << (ord(c) - ord(\"a\"))\n",
    "            for j, t in enumerate(words[:i]):\n",
    "                if (mask[i] & mask[j]) == 0:\n",
    "                    ans = max(ans, len(s) * len(t))\n",
    "        return ans"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maxProduct(self, words: List[str]) -> int:\n",
    "        ret = 0\n",
    "        bitWords = [0 for _ in words]\n",
    "        wordLengths = [0 for _ in words]\n",
    "        for i in range(len(words)):\n",
    "            for w in words[i]:\n",
    "                bitWords[i] |= (1 << (ord(w) - ord('a')))\n",
    "            wordLengths[i] = len(words[0])\n",
    "        for i in range(len(words)):\n",
    "            for j in range(i, len(words)):\n",
    "                if (bitWords[i] & bitWords[j]) == 0:\n",
    "                    ret = max(ret, len(words[i]) * len(words[j]))\n",
    "        return ret"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maxProduct(self, words: List[str]) -> int:\n",
    "        masks = defaultdict(int)\n",
    "        for word in words:\n",
    "            mask=reduce(lambda a, b : a | (1 << (ord(b) - ord('a'))), word, 0)\n",
    "            masks[mask] = max(masks[mask], len(word))\n",
    "        return max((masks[x] * masks[y] for x, y in product(masks, repeat=2) if x & y == 0), default=0)\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maxProduct(self, words: List[str]) -> int:\n",
    "        ans = 0\n",
    "        n = len(words)\n",
    "        mask = [0 for _ in range(0, n)]\n",
    "        for i in range(0, n):\n",
    "            line = words[i]\n",
    "            L = len(line)\n",
    "            for j in range(0, L):\n",
    "                mask[i] |=  ( 1 << (ord(line[j]) - ord('a')))\n",
    "        for i in range(0, n-1):\n",
    "            for j in range(i+1, n):\n",
    "                if mask[i] & mask[j] == 0:\n",
    "                    ans = max(ans, len(words[i])*len(words[j]))\n",
    "        return ans\n",
    "\n",
    "                "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maxProduct(self, words: List[str]) -> int:\n",
    "        mask = [0 for i in range(len(words))]\n",
    "        hash_table = {}\n",
    "        for i in range(len(words)):\n",
    "            word = words[i]\n",
    "            for c in word:\n",
    "                c = ord(c) - ord('a')\n",
    "                mask[i] = mask[i] | (1 << c)\n",
    "            if mask[i] in hash_table:\n",
    "                hash_table[mask[i]] = max(len(word), hash_table[mask[i]])\n",
    "            else:\n",
    "                hash_table[mask[i]] = len(word)\n",
    "        \n",
    "        \n",
    "        ans = 0\n",
    "        for mask1 in hash_table:\n",
    "            for mask2 in hash_table:\n",
    "                if (mask1 & mask2) == 0:\n",
    "                    ans = max(ans, hash_table[mask1]*hash_table[mask2])\n",
    "        return ans\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maxProduct(self, words: List[str]) -> int:\n",
    "        masks=defaultdict(int)\n",
    "        for word in words:\n",
    "            mask = reduce(lambda a, b: a | (1 << (ord(b) - ord('a'))), word, 0)\n",
    "            masks[mask] = max(masks[mask], len(word))\n",
    "        return max((masks[x] * masks[y] for x, y in product(masks, repeat=2) if x & y == 0), default=0)\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maxProduct(self, words: List[str]) -> int:\n",
    "        mask = [0] * len(words)\n",
    "        ans = 0\n",
    "        for i, s in enumerate(words):\n",
    "            for c in s:\n",
    "                mask[i] |= 1 << ord(c) - ord('a')\n",
    "            for j, t in enumerate(words[:i]):\n",
    "                if mask[i] & mask[j] == 0:\n",
    "                    ans = max(ans, len(s) * len(t))\n",
    "        return ans"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maxProduct(self, words: List[str]) -> int:\n",
    "        d = {}\n",
    "        for i in words:\n",
    "            x = 0\n",
    "            s = set(list(i))\n",
    "            for j in s:\n",
    "                x+=2**(ord(j)-ord('a'))\n",
    "            d[i] = x\n",
    "        words = sorted(words,key = lambda x: len(x),reverse = True)\n",
    "        mx = 0\n",
    "        for i in words:\n",
    "            for j in words:\n",
    "                if d[i] & d[j] == 0:\n",
    "                    mx = max(len(i)*len(j),mx)\n",
    "        return mx"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maxProduct(self, words: List[str]) -> int:\n",
    "        ans = 0\n",
    "        d = [ 0 ] * len(words)\n",
    "        for i in range(len(words)):\n",
    "            mask = 0\n",
    "            for k in words[i]:\n",
    "                mask |= 1 << (ord(k) - ord('a'))\n",
    "            d[i] = mask\n",
    "            for j in range(i):\n",
    "                if not (d[i] & d[j]):\n",
    "                    ans = max(ans, len(words[i]) * len(words[j]))\n",
    "        return ans"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maxProduct(self, words: List[str]) -> int:\n",
    "        mask = [0 for i in range(len(words))]\n",
    "        for i in range(len(words)):\n",
    "            word = words[i]\n",
    "            for c in word:\n",
    "                c = ord(c) - ord('a')\n",
    "                mask[i] = mask[i] | (1 << c)\n",
    "        \n",
    "        ans = 0\n",
    "        for i in range(len(words) - 1):\n",
    "            for j in range(i+1, len(words)):\n",
    "                if (mask[i] & mask[j] == 0):\n",
    "                    ans = max(ans, len(words[i]) * len(words[j]))\n",
    "        return ans\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maxProduct(self, words: List[str]) -> int:\n",
    "        masks = defaultdict(int)\n",
    "        for word in words:\n",
    "            mask=reduce(lambda a, b : a | (1 << (ord(b) - ord('a'))), word, 0)\n",
    "            masks[mask] = max(masks[mask], len(word))\n",
    "        return max((masks[x] * masks[y] for x, y in product(masks, repeat=2) if x & y == 0), default=0)\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maxProduct(self, words: List[str]) -> int:\n",
    "        res = 0\n",
    "        temp = [0] * len(words)\n",
    "        for i in range(len(words)):\n",
    "            val = 0\n",
    "            bit = [0] * 26\n",
    "            for j in range(len(words[i])):\n",
    "                bit[ord(words[i][j]) - ord('a')] = 1\n",
    "            for j in range(26):\n",
    "                val += bit[j] * 2 ** j\n",
    "            temp[i] = val\n",
    "        for i in range(len(words)):\n",
    "            for j in range(i + 1, len(words)):\n",
    "                if temp[i] & temp[j] == 0:\n",
    "                    res = max(res, len(words[i]) * len(words[j]))\n",
    "        return res\n",
    "        \n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maxProduct(self, words: List[str]) -> int:\n",
    "        bs = []\n",
    "        for w in words:\n",
    "            b = 0\n",
    "            for c in w:\n",
    "                i = ord(c) - ord(\"a\")\n",
    "                b |= 1 << i\n",
    "            bs.append(b)\n",
    "\n",
    "        ans = 0\n",
    "        for i, b in enumerate(bs):\n",
    "            for j in range(i, len(words)):\n",
    "                if b & bs[j] == 0:\n",
    "                    r = len(words[i]) * len(words[j])\n",
    "                    ans = max(ans, r)\n",
    "\n",
    "        return ans\n",
    "\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maxProduct(self, words: List[str]) -> int:\n",
    "        binary_words = []\n",
    "        for word in words:\n",
    "            x = 0\n",
    "            for c in word:\n",
    "                x |= 1 << (ord(c) - ord('a'))\n",
    "            binary_words.append(x)\n",
    "        n = len(words)\n",
    "        maxP = 0\n",
    "        for i in range(n):\n",
    "            for j in range(i + 1, n):\n",
    "                if binary_words[i] & binary_words[j] == 0:\n",
    "                    maxP = max(maxP, len(words[i]) * len(words[j]))\n",
    "        return maxP\n",
    "\n",
    "    "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\r\n",
    "    def maxProduct(self, words: List[str]) -> int:\r\n",
    "        d = {}\r\n",
    "        for word in words:\r\n",
    "            x = functools.reduce(lambda a, b: a | b, (1 << (ord(c) - ord('a')) for c in word), 0)\r\n",
    "            d[x] = max(d.get(x, 0), len(word))\r\n",
    "        ans = 0\r\n",
    "        for k1, l1 in d.items():\r\n",
    "            for k2, l2 in d.items():\r\n",
    "                if k1 & k2 == 0:\r\n",
    "                    ans = max(ans, l1 * l2)\r\n",
    "        return ans"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maxProduct(self, words: List[str]) -> int:\n",
    "        masks = [reduce(lambda a,b: a | (1 << (ord(b)-ord('a'))),word,0) for word in words]\n",
    "        return max((len(x[1]) * len(y[1]) for x,y in combinations(zip(masks,words), 2) if x[0] & y[0] == 0),default=0)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maxProduct(self, words: List[str]) -> int:\n",
    "        words.sort(key = lambda w : -len(w))\n",
    "        count = []\n",
    "        for w in words:\n",
    "            cur = 0\n",
    "            for c in w:\n",
    "                cur |= 1<<(ord(c)-ord(\"a\"))\n",
    "            count.append(cur)\n",
    "        res = 0\n",
    "        n = len(words)\n",
    "        for i in range(n-1):\n",
    "            for j in range(i+1, n):\n",
    "                if count[i] & count[j] == 0:\n",
    "                    res = max(res, len(words[i]) * len(words[j]))\n",
    "        return res\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maxProduct(self, words: List[str]) -> int:\n",
    "        masks = [reduce(lambda a, b: a | (1 << (ord(b) - ord('a'))), word, 0) for word in words]\n",
    "        return max((len(x[1]) * len(y[1]) for x, y in product(zip(masks, words), repeat=2) if x[0] & y[0] == 0), default=0)\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maxProduct(self, words: List[str]) -> int:\n",
    "        state_len_dict = dict()\n",
    "        ord_a = ord('a')\n",
    "        for word in words:\n",
    "            state = 0\n",
    "            for c in set(word):\n",
    "                state ^= 1 << (ord(c) - ord_a)\n",
    "            cur_len = state_len_dict.get(state, 0)\n",
    "            if cur_len < len(word):\n",
    "                state_len_dict[state] = len(word)\n",
    "        ret = 0\n",
    "        state_list = list(state_len_dict.keys())\n",
    "        n = len(state_list)\n",
    "        for i in range(n-1):\n",
    "            for j in range(i+1, n):\n",
    "                state1 = state_list[i]\n",
    "                state2 = state_list[j]\n",
    "                if state1 & state2 == 0:\n",
    "                    cur = state_len_dict[state1] * state_len_dict[state2]\n",
    "                    if cur > ret:\n",
    "                        ret = cur\n",
    "        return ret"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maxProduct(self, words: List[str]) -> int:\n",
    "        masks = [reduce(lambda a, b: a | (1 << (ord(b) - ord('a'))), word, 0) for word in words]\n",
    "        return max((len(x[1]) * len(y[1]) for x, y in product(zip(masks, words), repeat=2) if x[0] & y[0] == 0), default=0)\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maxProduct(self, words: List[str]) -> int:\n",
    "        masks = [reduce(lambda a, b: a | 1 << (ord(b) - ord('a')), w, 0) for w in words]\n",
    "        return max((len(x[1]) * len(y[1]) for x, y in product(zip(masks, words), repeat=2) if x[0] & y[0] == 0), default=0)\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maxProduct(self, words: List[str]) -> int:\n",
    "        ret = 0\n",
    "        letterSets = [set(l for l in w) for w in words]\n",
    "        for i in range(len(words)):\n",
    "            for j in range(i, len(words)):\n",
    "                if len(letterSets[i] & letterSets[j]) == 0:\n",
    "                    ret = max(ret, len(words[i]) * len(words[j]))\n",
    "        return ret"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maxProduct_02(self, words: List[str]) -> int:\n",
    "        res = 0\n",
    "        words = set(words)\n",
    "        words = list(words)\n",
    "        for i in range(len(words) - 1):\n",
    "            for j in range(i + 1, len(words)):\n",
    "                flag = True\n",
    "                for k in words[i]:\n",
    "                    if k in words[j]:\n",
    "                        flag = False\n",
    "                        break\n",
    "                if flag:\n",
    "                    res = max(res, len(words[i]) * len(words[j]))\n",
    "        return res\n",
    "\n",
    "    def maxProduct(self, words: List[str]) -> int:\n",
    "        n, l, s = len(words), list(map(len, words)), list(map(set, words))\n",
    "        return max((l[i] * l[j] for i, j in combinations(range(n), 2) if s[i] & s[j] == set()), default = 0)\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maxProduct(self, words: List[str]) -> int:\n",
    "        mask = [0] * len(words)\n",
    "        for i in range(len(words)):\n",
    "            for j in range(len(words[i])):\n",
    "                mask[i] |= 1 << (ord(words[i][j]) - ord('a')) \n",
    "        # print(mask)\n",
    "        res = 0\n",
    "        for i in range(len(words)):\n",
    "            for j in range(i + 1, len(words)):\n",
    "                if mask[i] & mask[j] == 0:\n",
    "                    print(i, j)\n",
    "                    res = max(res, len(words[i] * len(words[j])))\n",
    "        return res"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maxProduct(self, words: List[str]) -> int:\n",
    "        def get_mask(word):\n",
    "            mid = 0\n",
    "            for char in word:\n",
    "                mid |= 1<<(ord(char)-ord('a'))\n",
    "            return mid\n",
    "        mask = [get_mask(word) for word in words]\n",
    "        max_len = 0\n",
    "        for i in range(len(words)):\n",
    "            for j in range(i+1,len(words)):\n",
    "                if mask[i]&mask[j] == 0:\n",
    "                    max_len = max(max_len,len(words[i])*len(words[j]))\n",
    "        return max_len"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maxProduct(self, words: List[str]) -> int:\n",
    "        masks = [reduce(lambda a, b: a | (1 << (ord(b) - ord('a'))), w, 0) for w in words]\n",
    "        return max((len(x[1]) * len(y[1]) for x, y in product(zip(masks, words), repeat=2) if x[0] & y[0] == 0), default=0)\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maxProduct(self, words: List[str]) -> int:\n",
    "        newWord = []\n",
    "        l = len(words)\n",
    "        for i in words:\n",
    "            newWord.append([set(i),len(i)])\n",
    "        res = 0\n",
    "        newWord.sort(key=lambda x:x[1],reverse=True)\n",
    "        for i in range(l-1):\n",
    "            a = newWord[i]\n",
    "            if len(a[0]) == 26:\n",
    "                continue\n",
    "            if a[1]*newWord[i+1][1]<res:\n",
    "                break\n",
    "            for j in range(i+1,l):\n",
    "                b = newWord[j]\n",
    "                if a[1]*b[1]<res:\n",
    "                    break\n",
    "                if len(a[0]&b[0])>0:\n",
    "                    continue\n",
    "                res = max(res,a[1]*b[1])\n",
    "        return res"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maxProduct(self, words: List[str]) -> int:\n",
    "        mask = [0] * len(words)\n",
    "        print(mask)\n",
    "        ans = 0\n",
    "        for i, s in enumerate(words):\n",
    "            for c in s:\n",
    "                mask[i] |= 1 << (ord(c) - ord(\"a\"))\n",
    "            print('mask[i]', bin(mask[i]))\n",
    "            for j, t in enumerate(words[:i]):\n",
    "                if (mask[i] & mask[j]) == 0:\n",
    "                    ans = max(ans, len(s) * len(t))\n",
    "        return ans\n",
    "\n",
    "\n",
    "     "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maxProduct(self, words: List[str]) -> int:\n",
    "        ws = [set(s) for s in words]\n",
    "        rt = 0\n",
    "        for i, word1 in enumerate(words):\n",
    "            for j, word2 in enumerate(words[i:]):\n",
    "                if len(ws[i].intersection(ws[j+i])) == 0:\n",
    "                    t = len(word1) * len(word2)\n",
    "                    if rt < t:\n",
    "                        rt = t\n",
    "        return rt\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maxProduct(self, words: List[str]) -> int:\n",
    "        ans = 0\n",
    "        sets = [set(word) for word in words]\n",
    "        for i in range(len(words)):\n",
    "            for j in range(i + 1, len(words)):\n",
    "                if not sets[i] & sets[j]:\n",
    "                    ans = max(ans, len(words[i]) * len(words[j]))\n",
    "        return ans\n",
    "        "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maxProduct(self, words: List[str]) -> int:\n",
    "        masks = [reduce(lambda a, b: a | (1 << (ord(b) - ord('a'))), word, 0) for word in words]\n",
    "        return max((len(x[1]) * len(y[1]) for x, y in product(zip(masks, words), repeat=2) if x[0] & y[0] == 0), default=0)\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maxProduct(self, words: List[str]) -> int:\n",
    "        words_data = list()\n",
    "        for word in words:\n",
    "            words_data.append((word, set(word), len(word)))\n",
    "        result = 0\n",
    "        for i in range(len(words_data)):\n",
    "            for j in range(i+1, len(words_data)):\n",
    "                if not (words_data[i][1] & words_data[j][1]):\n",
    "                    result = max(result, words_data[i][2] * words_data[j][2])\n",
    "        return result"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maxProduct(self, words: List[str]) -> int:\n",
    "        words_set = [set(x) for x in words]\n",
    "        res, n = 0, len(words)\n",
    "        for i in range(n-1):\n",
    "            for j in range(i+1, n):\n",
    "                temp = set()\n",
    "                temp.update(words[i])\n",
    "                temp.update(words_set[j])\n",
    "                if len(temp) == len(words_set[i]) + len(words_set[j]):\n",
    "                    res = max(res, len(words[i]) * len(words[j]))\n",
    "        return res"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maxProduct(self, words: List[str]) -> int:\n",
    "        arr=[(len(word),set(word)) for word in words]\n",
    "        arr.sort(reverse=True)\n",
    "        n=len(words)\n",
    "        ans=0\n",
    "        for i in range(n):\n",
    "            for j in range(i+1,n):\n",
    "                if not arr[i][1]&arr[j][1]:\n",
    "                    ans=max(ans,arr[i][0]*arr[j][0])\n",
    "                    break\n",
    "        return ans"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maxProduct(self, words: List[str]) -> int:\n",
    "        masks = [reduce(lambda a, b: a | (1 << (ord(b) - ord('a'))), word, 0) for word in words]\n",
    "        return max((len(x[1]) * len(y[1]) for x, y in product(zip(masks, words), repeat=2) if x[0] & y[0] == 0), default=0)\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maxProduct(self, words: List[str]) -> int:\n",
    "        ws = []\n",
    "        n = len(words)\n",
    "        ans = 0\n",
    "        for x in words:\n",
    "            ws.append(set(x))\n",
    "        for i in range(n):\n",
    "            for j in range(i + 1, n):\n",
    "                if len(ws[i] | ws[j]) == len(ws[i]) + len(ws[j]):\n",
    "                    ans = max(ans, len(words[i]) * len(words[j]))\n",
    "        return ans\n"
   ]
  }
 ],
 "metadata": {},
 "nbformat": 4,
 "nbformat_minor": 2
}
